Files
options_backtester/backtester/strategy/strategy.py
T
2020-03-19 11:52:24 -03:00

72 lines
2.2 KiB
Python

import math
import numpy as np
class Strategy:
"""Options strategy class.
Takes in a number of `StrategyLeg`'s (option contracts), and filters that determine
entry and exit conditions.
"""
def __init__(self, schema):
self.schema = schema
self.legs = []
self.conditions = []
self.exit_thresholds = (math.inf, math.inf)
def add_leg(self, leg):
"""Adds leg to the strategy"""
assert self.schema == leg.schema
leg.name = "leg_{}".format(len(self.legs) + 1)
self.legs.append(leg)
return self
def add_legs(self, legs):
"""Adds legs to the strategy"""
for leg in legs:
self.add_leg(leg)
return self
def remove_leg(self, leg_number):
"""Removes leg from the strategy"""
self.legs.pop(leg_number)
return self
def clear_legs(self):
"""Removes *all* legs from the strategy"""
self.legs = []
return self
def add_exit_thresholds(self, profit_pct=math.inf, loss_pct=math.inf):
"""Adds maximum profit/loss thresholds. Both **must** be >= 0.0
Args:
profit_pct (float, optional): Max profit level. Defaults to math.inf
loss_pct (float, optional): Max loss level. Defaults to math.inf
"""
assert profit_pct >= 0
assert loss_pct >= 0
self.exit_thresholds = (profit_pct, loss_pct)
def filter_thresholds(self, entry_cost, current_cost):
"""Returns a `pd.Series` of booleans indicating where profit (loss) levels
exceed the given thresholds.
Args:
entry_cost (pd.Series): Total _entry_ cost of inventory row.
current_cost (pd.Series): Present cost of inventory row.
Returns:
pd.Series: Indicator series with `True` for every row that
exceeds the specified profit/loss thresholds.
"""
profit_pct, loss_pct = self.exit_thresholds
excess_return = (current_cost / entry_cost + 1) * -np.sign(entry_cost)
return (excess_return >= profit_pct) | (excess_return <= -loss_pct)
def __repr__(self):
return "Strategy(legs={}, exit_thresholds={})".format(self.legs, self.exit_thresholds)