class FXBarrierHedgingStrategy(sig.DailyStrategy):
strategy_name = StringType(required=True)
maturity = StringType(required=True)
rebalance_frequency = StringType(required=True)
group_name = StringType(required=True)
bdc = StringType(default=sig.calendar.BDC_PRECEDING)
super(FXBarrierHedgingStrategy, self).__init__()
self.option_group = sig.obj.get(self.group_name)
self._strategy = sig.obj.get(self.strategy_name)
self.over = self._strategy.currency
self.under = self.currency
def schedule_information(self):
""" set the holiday calendar for rebalancing - Here we use the the same holidays as the global trading manager """
return StrategySchedule(holidays=sig.TradingManager.instance().trading_holidays)
def get_rebalance_dates(self):
helper function to get all the rebalance dates based on the rebalance schedule and market holidays
first_date = self.calendar_schedule().next_data_date(self.start_date)
all_dates = sig.SchedulePeriodic(self.start_date, self.calculation_end_date(),
self.history_schedule().approximate_holidays(),
frequency=self.rebalance_frequency, bdc=self.bdc).all_data_dates()[1:]
return [first_date] + all_dates
def strategy_initialization(self, dt):
""" This is the first function to start the strategy building process. """
self.add_method(self.first_entry_date, self.push_strategy)
rebalance_dates = self.get_rebalance_dates()
for d in rebalance_dates:
self.add_method(d, self.enter_barrier_option_positions)
def push_strategy(self, dt):
self.add_position_target(dt, self.strategy_name, 1.0, unit_type='WEIGHT')
self.add_method(self.valuation_dt(dt.date()),
self.clean_up_foreign_cash)
def clean_up_foreign_cash(self, dt):
for cash_instrument, quantity in self.positions.iterate_cash_positions(dt):
if cash_instrument.currency != self.currency:
self.add_fx_spot_trade(dt, self.currency,
cash_instrument.currency, -quantity)
def enter_barrier_option_positions(self, dt):
""" This process determines the barrier option parameters. """
# first close out existing fx forwards
for instrument, quantity in self.positions.iterate_instruments(dt):
if instrument.is_option():
self.add_position_target(dt, instrument.name, 0.0, unit_type='WEIGHT')
size_date = self.size_date_from_decision_dt(dt)
notional_ccy = self.valuation_price(size_date, ccy=self.over)
maturity_date = self.option_group.convert_maturity_tenor_to_date(
size_date, self.maturity, target_maturity_weekday=3)
atm = sig.obj.get(self.option_group.underlying).history().asof(pd.to_datetime(size_date))
barrier_option = self.option_group.get_option(
'Put', atm, size_date, maturity_date, barrier_type='KI', barrier=atm * 0.99)
self.add_position_target(dt, barrier_option.name, notional_ccy)