pybottrader.traders API documentation

# pybottrader.traders

A collection of bottraders

Traders, these are bots that based on a data stream, a strategy, and a portfolio, run the trading operations. Currently only a basic Trader is offered, useful for back-testing.

View Source

     1"""
     2A collection of bottraders
     3
     4Traders, these are bots that based on a data stream, a strategy, and a
     5portfolio, run the trading operations. Currently only a basic Trader is offered,
     6useful for back-testing.
     7
     8"""
     9
    10from typing import Union
    11from attrs import define
    12from .datastreamers import DataStreamer
    13from .portfolios import Portfolio
    14from .strategies import Strategy, Position, StrategySignal
    15from .indicators import roi
    16
    17
    18@define
    19class TradingIteration:
    20    """Used to report results from a trading iteration"""
    21
    22    signal: StrategySignal
    23    data: dict
    24    roi: Union[float, None]
    25    portfolio_value: float
    26    accumulated_roi: Union[float, None]
    27
    28
    29class Trader:
    30    """Base class"""
    31
    32    portfolio: Portfolio
    33    datastream: DataStreamer
    34    strategy: Strategy
    35    last_result: Union[TradingIteration, None] = None
    36    last_valuation: float = 0.0
    37
    38    def __init__(
    39        self,
    40        strategy: Strategy,
    41        portfolio: Portfolio,
    42        datastream: DataStreamer,
    43    ):
    44        """Init method"""
    45        self.datastream = datastream
    46        self.portfolio = portfolio
    47        self.strategy = strategy
    48
    49    def next(self) -> bool:
    50        """Perfoms a trading iteration"""
    51        obs = self.datastream.next()
    52        if obs is None:
    53            return False
    54        signal = self.strategy.evaluate(data=obs)
    55        self.portfolio.process(signal)
    56        self.last_result = TradingIteration(
    57            signal=signal,
    58            data=obs,
    59            roi=roi(self.last_valuation, self.portfolio.valuation()),
    60            portfolio_value=self.portfolio.valuation(),
    61            accumulated_roi=self.portfolio.accumulated_return(),
    62        )
    63        self.last_valuation = self.portfolio.valuation()
    64        return True
    65
    66    def status(self) -> TradingIteration:
    67        """Trader last result"""
    68        return self.last_result
    69
    70    def run(self):
    71        """A default runner"""
    72        # A nice header
    73        print(
    74            "{:25} {:4} {:>10} {:>10}  {:>10} {:>10}".format(  # pylint: disable=consider-using-f-string
    75                "Time", "Pos.", "Price", "ROI", "Valuation", "Accum.ROI"
    76            )
    77        )
    78        # Run the back-testing
    79        while self.next():
    80            status = self.status()
    81            if status.signal.position != Position.STAY:
    82                # A nice output
    83                print(
    84                    f"{status.signal.time} "
    85                    + f"{status.signal.position.name:4} "
    86                    + f"{status.data['close']:10.2f} "
    87                    + f"{status.roi * 100.0:10.2f}% "
    88                    + f"{status.portfolio_value:10.2f} "
    89                    + f"{status.accumulated_roi * 100.0:10.2f}%"
    90                )

@define
class TradingIteration: View Source

    19@define
    20class TradingIteration:
    21    """Used to report results from a trading iteration"""
    22
    23    signal: StrategySignal
    24    data: dict
    25    roi: Union[float, None]
    26    portfolio_value: float
    27    accumulated_roi: Union[float, None]

Used to report results from a trading iteration

TradingIteration( signal: pybottrader.strategies.StrategySignal, data: dict, roi: Optional[float], portfolio_value: float, accumulated_roi: Optional[float]) View Source

    2def __init__(self, signal, data, roi, portfolio_value, accumulated_roi):
    3    self.signal = signal
    4    self.data = data
    5    self.roi = roi
    6    self.portfolio_value = portfolio_value
    7    self.accumulated_roi = accumulated_roi

Method generated by attrs for class TradingIteration.

signal: pybottrader.strategies.StrategySignal
data: dict
roi: Optional[float]
portfolio_value: float
accumulated_roi: Optional[float]
class Trader: View Source

    30class Trader:
    31    """Base class"""
    32
    33    portfolio: Portfolio
    34    datastream: DataStreamer
    35    strategy: Strategy
    36    last_result: Union[TradingIteration, None] = None
    37    last_valuation: float = 0.0
    38
    39    def __init__(
    40        self,
    41        strategy: Strategy,
    42        portfolio: Portfolio,
    43        datastream: DataStreamer,
    44    ):
    45        """Init method"""
    46        self.datastream = datastream
    47        self.portfolio = portfolio
    48        self.strategy = strategy
    49
    50    def next(self) -> bool:
    51        """Perfoms a trading iteration"""
    52        obs = self.datastream.next()
    53        if obs is None:
    54            return False
    55        signal = self.strategy.evaluate(data=obs)
    56        self.portfolio.process(signal)
    57        self.last_result = TradingIteration(
    58            signal=signal,
    59            data=obs,
    60            roi=roi(self.last_valuation, self.portfolio.valuation()),
    61            portfolio_value=self.portfolio.valuation(),
    62            accumulated_roi=self.portfolio.accumulated_return(),
    63        )
    64        self.last_valuation = self.portfolio.valuation()
    65        return True
    66
    67    def status(self) -> TradingIteration:
    68        """Trader last result"""
    69        return self.last_result
    70
    71    def run(self):
    72        """A default runner"""
    73        # A nice header
    74        print(
    75            "{:25} {:4} {:>10} {:>10}  {:>10} {:>10}".format(  # pylint: disable=consider-using-f-string
    76                "Time", "Pos.", "Price", "ROI", "Valuation", "Accum.ROI"
    77            )
    78        )
    79        # Run the back-testing
    80        while self.next():
    81            status = self.status()
    82            if status.signal.position != Position.STAY:
    83                # A nice output
    84                print(
    85                    f"{status.signal.time} "
    86                    + f"{status.signal.position.name:4} "
    87                    + f"{status.data['close']:10.2f} "
    88                    + f"{status.roi * 100.0:10.2f}% "
    89                    + f"{status.portfolio_value:10.2f} "
    90                    + f"{status.accumulated_roi * 100.0:10.2f}%"
    91                )

Base class

Trader( strategy: pybottrader.strategies.Strategy, portfolio: pybottrader.portfolios.Portfolio, datastream: pybottrader.datastreamers.DataStreamer) View Source

    39    def __init__(
    40        self,
    41        strategy: Strategy,
    42        portfolio: Portfolio,
    43        datastream: DataStreamer,
    44    ):
    45        """Init method"""
    46        self.datastream = datastream
    47        self.portfolio = portfolio
    48        self.strategy = strategy

Init method

portfolio: pybottrader.portfolios.Portfolio
datastream: pybottrader.datastreamers.DataStreamer
strategy: pybottrader.strategies.Strategy
last_result: Optional[TradingIteration] = None
last_valuation: float = 0.0
def next(self) -> bool: View Source

    50    def next(self) -> bool:
    51        """Perfoms a trading iteration"""
    52        obs = self.datastream.next()
    53        if obs is None:
    54            return False
    55        signal = self.strategy.evaluate(data=obs)
    56        self.portfolio.process(signal)
    57        self.last_result = TradingIteration(
    58            signal=signal,
    59            data=obs,
    60            roi=roi(self.last_valuation, self.portfolio.valuation()),
    61            portfolio_value=self.portfolio.valuation(),
    62            accumulated_roi=self.portfolio.accumulated_return(),
    63        )
    64        self.last_valuation = self.portfolio.valuation()
    65        return True

Perfoms a trading iteration

def status(self) -> TradingIteration: View Source

    67    def status(self) -> TradingIteration:
    68        """Trader last result"""
    69        return self.last_result

Trader last result

def run(self): View Source

    71    def run(self):
    72        """A default runner"""
    73        # A nice header
    74        print(
    75            "{:25} {:4} {:>10} {:>10}  {:>10} {:>10}".format(  # pylint: disable=consider-using-f-string
    76                "Time", "Pos.", "Price", "ROI", "Valuation", "Accum.ROI"
    77            )
    78        )
    79        # Run the back-testing
    80        while self.next():
    81            status = self.status()
    82            if status.signal.position != Position.STAY:
    83                # A nice output
    84                print(
    85                    f"{status.signal.time} "
    86                    + f"{status.signal.position.name:4} "
    87                    + f"{status.data['close']:10.2f} "
    88                    + f"{status.roi * 100.0:10.2f}% "
    89                    + f"{status.portfolio_value:10.2f} "
    90                    + f"{status.accumulated_roi * 100.0:10.2f}%"
    91                )

A default runner