Ejemplo n.º 1
0
    def _execution_price(self, data_handler: DataHandler) -> float:
        btic_fixings = data_handler.get_data_range(self.window.start, self.window.end,
                                                   self.btic_instrument, ValuationFixingType.PRICE)
        btic_twap = np.mean(btic_fixings)
        close = data_handler.get_data(self.window.end.date(), self.instrument, ValuationFixingType.PRICE)

        return close + btic_twap
Ejemplo n.º 2
0
 def _execution_price(self, data_handler: DataHandler) -> float:
     if self.executed_price is None:
         btic_fixings = data_handler.get_data_range(self.window.start, self.window.end,
                                                    self.btic_instrument, ValuationFixingType.PRICE)
         btic_twap = np.mean(btic_fixings)
         close = data_handler.get_data(self.window.end.date(), self.future_underlying)
         self.executed_price = close + btic_twap
     return self.executed_price
Ejemplo n.º 3
0
 def __init__(self,
              data_mgr: DataManager,
              calendars: Union[str, Tuple[str, ...]],
              tz: timezone,
              valuation_method: ValuationMethod,
              action_impl_map={}):
     self.action_impl_map = action_impl_map
     self.calendars = calendars
     self.tz = tz
     self.data_handler = DataHandler(data_mgr, tz=tz)
     self.valuation_method = valuation_method
     self.execution_engine = None
Ejemplo n.º 4
0
 def _execution_price(self, data_handler: DataHandler) -> float:
     if self.executed_price is None:
         fixings = data_handler.get_data_range(self.window.start,
                                               self.window.end,
                                               self.instrument,
                                               ValuationFixingType.PRICE)
         self.executed_price = np.mean(fixings)
     return self.executed_price
Ejemplo n.º 5
0
 def _execution_price(self, data_handler: DataHandler) -> float:
     return data_handler.get_data(self.execution_datetime, self.instrument,
                                  ValuationFixingType.PRICE)
Ejemplo n.º 6
0
 def _execution_price(self, data_handler: DataHandler) -> float:
     if self.executed_price is None:
         self.executed_price = data_handler.get_data(self.execution_datetime,
                                                     self.instrument, ValuationFixingType.PRICE)
     return self.executed_price
Ejemplo n.º 7
0
 def execution_price(self, data_handler: DataHandler) -> float:
     fixings = data_handler.get_data_range(self.window.start,
                                           self.window.end, self.instrument,
                                           ValuationFixingType.PRICE)
     return np.mean(fixings)
Ejemplo n.º 8
0
class GenericPriceEngine(BacktestBaseEngine):
    def get_action_handler(self, action: Action) -> Action:
        handler_factory = GenericPriceEngineActionFactory(self.action_impl_map)
        return handler_factory.get_action_handler(action)

    @classmethod
    def supports_strategy(cls, strategy):
        all_actions = reduce(lambda x, y: x + y,
                             (map(lambda x: x.actions, strategy.triggers)))
        try:
            for x in all_actions:
                cls.get_action_handler(x)
        except RuntimeError:
            return False
        return True

    def __init__(self,
                 data_mgr: DataManager,
                 calendars: Union[str, Tuple[str, ...]],
                 tz: timezone,
                 valuation_method: ValuationMethod,
                 action_impl_map={}):
        self.action_impl_map = action_impl_map
        self.calendars = calendars
        self.tz = tz
        self.data_handler = DataHandler(data_mgr, tz=tz)
        self.valuation_method = valuation_method
        self.execution_engine = None

    def _eod_valuation_time(self):
        if self.valuation_method.window:
            return self.valuation_method.window.end
        else:
            return dt.time(23)

    def _timer(self, strategy, start, end):
        dates = date_range(start, end, calendars=self.calendars)
        times = list(strategy.triggers[0].get_trigger_times())
        times.append(self._eod_valuation_time())
        times = list(dict.fromkeys(times))

        for d in dates:
            for t in times:
                yield dt.datetime.combine(d, t)

    def run_backtest(self, strategy, start, end):
        # initialize backtest object
        backtest = PriceBacktest(self.data_handler)
        backtest.set_start_date(start)

        # initialize execution engine
        self.execution_engine = SimulatedExecutionEngine(self.data_handler)

        # create timer
        timer = self._timer(strategy, start, end)
        self._run(strategy, timer, backtest)
        return backtest

    def _run(self, strategy, timer, backtest: PriceBacktest):
        events = deque()

        while True:
            try:
                state = next(timer)
            except StopIteration:
                break

            # update to latest data
            self.data_handler.update(state)

            # see if any submitted orders have been executed
            fills = self.execution_engine.ping(state)
            events.extend(fills)

            # generate a market event
            events.append(MarketEvent())

            # create valuation event when it's due for daily valuation
            if state.time() == self._eod_valuation_time():
                events.append(ValuationEvent())

            while events:
                event = events.popleft()

                if event.type == 'Market':  # market event (new mkt data coming in)
                    for trigger in strategy.triggers:
                        if trigger.has_triggered(state, backtest):
                            for action in trigger.actions:
                                orders = self.get_action_handler(
                                    action).apply_action(state, backtest)
                                backtest.record_orders(orders)
                                events.extend([OrderEvent(o) for o in orders])
                elif event.type == 'Order':  # order event (submit the order to execution engine)
                    self.execution_engine.submit_order(event)
                elif event.type == 'Fill':  # fill event (update backtest with the fill results)
                    backtest.update_fill(event)
                elif event.type == 'Valuation':  # valuation event (calculate daily level)
                    backtest.mark_to_market(state, self.valuation_method)

        return backtest