from .index import Index from .option import BlackSwaption class Portfolio: def __init__(self, trades): self.trades = trades self.indices = [t for t in trades if isinstance(t, Index)] self.swaptions = [t for t in trades if isinstance(t, BlackSwaption)] @property def pnl(self): return sum(t.pnl for t in self.trades) @property def pnl_list(self): return [t.pnl for t in self.trades] @property def pv(self): return sum(t.pv for t in self.trades) @property def pv_list(self): return [t.pv for t in self.trades] def set_original_pv(self): for t in self.trades: t.set_original_pv() @property def trade_date(self): return self.index.trade_date @trade_date.setter def trade_date(self, d): for index in self.indices: index.trade_date = d def mark(self): pass @property def ref(self): if len(self.indices) == 1: return self.indices[0].ref else: return [index.ref for index in self.indices] @ref.setter def ref(self, val): if len(self.indices) == 1: self.indices[0].ref = val elif len(self.indices) == 0: ##no index, so set the individual refs for t in trades: t.index.ref = val elif len(self.indices) == len(val): for index, val in zip(self.indices, val): index.ref = val else: raise ValueError("The number of refs doesn't match the number of indices") @property def delta(self): """returns the equivalent protection notional makes sense only where there is a single index.""" return sum([getattr(t, 'delta', -t._direction) * t.notional for t in self.trades]) @property def gamma(self): return sum([getattr(t, 'gamma', 0) * t.notional for t in self.trades]) @property def dv01(self): return sum(t.dv01 for t in self.trades)