pybottrader.portfolios
Portfolio Managers
Portfolio managers, to implement buy/sell policies and deliver orders.
Currently only a DummyPortfolio
is implemented, one that when receives a buy
signal buys everything that it can with its available cash, and sells all its
assets when receives a sell
signal. This portfolio can be used for
back-testing.
1""" 2# Portfolio Managers 3 4Portfolio managers, to implement buy/sell policies and deliver orders. 5Currently only a `DummyPortfolio` is implemented, one that when receives a `buy` 6signal buys everything that it can with its available cash, and sells all its 7assets when receives a `sell` signal. This portfolio can be used for 8back-testing. 9""" 10 11from .strategies import Position, StrategySignal 12from .indicators import roi 13 14 15class Portfolio: 16 """Base Portfolio Class""" 17 18 initial_cash: float 19 last_position: Position 20 last_exchange: str 21 last_price: float 22 last_ticker: str 23 24 def __init__(self, cash: float = 1000.0): 25 """Init method""" 26 self.initial_cash = cash 27 self.last_position = Position.STAY 28 self.last_price = 0.0 29 self.last_ticker = "" 30 self.last_exchange = "" 31 32 def process(self, signal: StrategySignal): 33 """Process signal""" 34 self.last_ticker = signal.ticker 35 self.last_price = signal.price 36 self.last_position = signal.position 37 self.last_exchange = signal.exchange 38 39 def valuation(self) -> float: 40 """Default valuation method""" 41 return self.initial_cash 42 43 def accumulated_return(self) -> float: 44 """Accumulated ROI""" 45 return roi(self.initial_cash, self.valuation()) 46 47 48class DummyPortfolio(Portfolio): 49 """ 50 Dummy portfolio is the most basic portfolio model. 51 It works with only one asset. When it receives the buy signal, 52 it uses all the available cash to buy the asset. When it receives 53 the sell signal, it sells all the shares of the asset. 54 """ 55 56 cash: float 57 share_units: float 58 share_price: float 59 60 def __init__(self, cash: float = 1000.0): 61 super().__init__(cash) 62 self.cash = cash 63 self.share_units = 0.0 64 self.share_price = 0.0 65 66 def process(self, signal: StrategySignal): 67 super().process(signal) 68 if signal.position == Position.BUY: 69 if self.cash == 0.0: 70 return 71 self.share_units = self.cash / signal.price 72 self.share_price = signal.price 73 self.cash = 0.0 74 elif signal.position == Position.SELL: 75 if self.share_units == 0.0: 76 return 77 self.cash = self.share_units * signal.price 78 self.share_price = signal.price 79 self.share_units = 0.0 80 81 def valuation(self) -> float: 82 return self.cash if self.cash > 0.0 else (self.share_price * self.share_units)
class
Portfolio:
16class Portfolio: 17 """Base Portfolio Class""" 18 19 initial_cash: float 20 last_position: Position 21 last_exchange: str 22 last_price: float 23 last_ticker: str 24 25 def __init__(self, cash: float = 1000.0): 26 """Init method""" 27 self.initial_cash = cash 28 self.last_position = Position.STAY 29 self.last_price = 0.0 30 self.last_ticker = "" 31 self.last_exchange = "" 32 33 def process(self, signal: StrategySignal): 34 """Process signal""" 35 self.last_ticker = signal.ticker 36 self.last_price = signal.price 37 self.last_position = signal.position 38 self.last_exchange = signal.exchange 39 40 def valuation(self) -> float: 41 """Default valuation method""" 42 return self.initial_cash 43 44 def accumulated_return(self) -> float: 45 """Accumulated ROI""" 46 return roi(self.initial_cash, self.valuation())
Base Portfolio Class
Portfolio(cash: float = 1000.0)
25 def __init__(self, cash: float = 1000.0): 26 """Init method""" 27 self.initial_cash = cash 28 self.last_position = Position.STAY 29 self.last_price = 0.0 30 self.last_ticker = "" 31 self.last_exchange = ""
Init method
last_position: pybottrader.strategies.Position
33 def process(self, signal: StrategySignal): 34 """Process signal""" 35 self.last_ticker = signal.ticker 36 self.last_price = signal.price 37 self.last_position = signal.position 38 self.last_exchange = signal.exchange
Process signal
49class DummyPortfolio(Portfolio): 50 """ 51 Dummy portfolio is the most basic portfolio model. 52 It works with only one asset. When it receives the buy signal, 53 it uses all the available cash to buy the asset. When it receives 54 the sell signal, it sells all the shares of the asset. 55 """ 56 57 cash: float 58 share_units: float 59 share_price: float 60 61 def __init__(self, cash: float = 1000.0): 62 super().__init__(cash) 63 self.cash = cash 64 self.share_units = 0.0 65 self.share_price = 0.0 66 67 def process(self, signal: StrategySignal): 68 super().process(signal) 69 if signal.position == Position.BUY: 70 if self.cash == 0.0: 71 return 72 self.share_units = self.cash / signal.price 73 self.share_price = signal.price 74 self.cash = 0.0 75 elif signal.position == Position.SELL: 76 if self.share_units == 0.0: 77 return 78 self.cash = self.share_units * signal.price 79 self.share_price = signal.price 80 self.share_units = 0.0 81 82 def valuation(self) -> float: 83 return self.cash if self.cash > 0.0 else (self.share_price * self.share_units)
Dummy portfolio is the most basic portfolio model. It works with only one asset. When it receives the buy signal, it uses all the available cash to buy the asset. When it receives the sell signal, it sells all the shares of the asset.
DummyPortfolio(cash: float = 1000.0)
61 def __init__(self, cash: float = 1000.0): 62 super().__init__(cash) 63 self.cash = cash 64 self.share_units = 0.0 65 self.share_price = 0.0
Init method
67 def process(self, signal: StrategySignal): 68 super().process(signal) 69 if signal.position == Position.BUY: 70 if self.cash == 0.0: 71 return 72 self.share_units = self.cash / signal.price 73 self.share_price = signal.price 74 self.cash = 0.0 75 elif signal.position == Position.SELL: 76 if self.share_units == 0.0: 77 return 78 self.cash = self.share_units * signal.price 79 self.share_price = signal.price 80 self.share_units = 0.0
Process signal
def
valuation(self) -> float:
82 def valuation(self) -> float: 83 return self.cash if self.cash > 0.0 else (self.share_price * self.share_units)
Default valuation method