Example #1
0
    def calculate_signals(self, event):
        if (event.type == EventType.BAR and event.ticker == self.ticker):
            # Add latest adjusted closing price to the
            # short and long window bars
            self.lw_bars.append(event.adj_close_price)
            if self.bars > self.long_window - self.short_window:
                self.sw_bars.append(event.adj_close_price)

            # Enough bars are present for trading
            if self.bars > self.long_window:
                # Calculate the simple moving averages
                short_sma = np.mean(self.sw_bars)
                long_sma = np.mean(self.lw_bars)
                # Trading signals based on moving average cross
                if short_sma > long_sma and not self.invested:
                    print("LONG %s: %s" % (self.ticker, event.time))
                    signal = SignalEvent(self.ticker,
                                         "BOT",
                                         suggested_quantity=self.base_quantity)
                    self.events_queue.put(signal)
                    self.invested = True
                elif short_sma < long_sma and self.invested:
                    print("SHORT %s: %s" % (self.ticker, event.time))
                    signal = SignalEvent(self.ticker,
                                         "SLD",
                                         suggested_quantity=self.base_quantity)
                    self.events_queue.put(signal)
                    self.invested = False
            self.bars += 1
Example #2
0
    def calculate_signals(self, event):
        if (event.type in [EventType.BAR, EventType.TICK]
                and event.ticker == self.ticker
                and self._end_of_month_trading_calendar(event.time)):
            ticker = event.ticker
            if self.invested:
                liquidate_signal = SignalEvent(ticker, "EXIT")
                self.events_queue.put(liquidate_signal)
            long_signal = SignalEvent(ticker, "BOT")
            self.events_queue.put(long_signal)

            self.invested = True
Example #3
0
 def calculate_signals(self, event):
     """
     For a particular received BarEvent, determine whether
     it is the end of the month (for that bar)/ quarter / year and generate
     a liquidation signal, as well as a purchase signal,
     for each ticker.
     """
     if (event.type in [EventType.BAR, EventType.TICK]
             and self._end_of_quarter(event.time)):
         ticker = event.ticker
         if self.tickers_invested[ticker]:
             liquidate_signal = SignalEvent(ticker, "EXIT")
             self.events_queue.put(liquidate_signal)
         long_signal = SignalEvent(ticker, "BOT")
         self.events_queue.put(long_signal)
         self.tickers_invested[ticker] = True
Example #4
0
    def calculate_signals(self, event):
        if (event.type == EventType.BAR and event.ticker == self.ticker):
            # print("what type of price is in the event", event.adj_close_price, type(event.adj_close_price))
            # print("Our dataframe looks like this ", self.prices_df)
            self.prices_df = self.prices_df.append(
                {event.ticker: event.adj_close_price}, ignore_index=True)

            # self.prices_df[self.bars] = event.adj_close_price
            if self.bars == 0:
                print(self.prices_df)
            # if we have enough bars for the third window
            if self.bars > self.third_window + 1:
                if self.bars % self.trade_freq == 0:
                    # print(self.prices_df.tail(5))
                    # calculate the 1 month, 3 month, 6 month returns
                    # current_price = self.prices_df.iloc[-1][ticker]
                    current_price = self.prices_df.iloc[-1]
                    one_month = (current_price -
                                 self.prices_df.iloc[-1 - self.first_window]
                                 ) / current_price
                    three_month = (current_price -
                                   self.prices_df.iloc[-1 - self.second_window]
                                   ) / current_price
                    six_month = (current_price -
                                 self.prices_df.iloc[-1 - self.third_window]
                                 ) / current_price

                    accelerating_momo = np.mean(
                        [one_month, three_month, six_month])

                    if accelerating_momo > 0 and not self.invested:
                        print("LONG %s: %s " % (self.ticker, event.time))
                        signal = SignalEvent(
                            self.ticker,
                            "BOT",
                            suggested_quantity=self.base_quantity)
                        self.events_queue.put(signal)
                        self.invested = True
                    elif accelerating_momo < 0 and self.invested:
                        print("SELLING %s: %s" % (self.ticker, event.time))
                        signal = SignalEvent(
                            self.ticker,
                            "SLD",
                            suggested_quantity=self.base_quantity)
                        self.events_queue.put(signal)
                        self.invested = False
            self.bars += 1
Example #5
0
 def calculate_signals(self, event):
     if (event.type in [EventType.BAR, EventType.TICK]
             and event.ticker == self.ticker):
         if not self.invested and self.bars == 0:
             signal = SignalEvent(self.ticker,
                                  "BOT",
                                  suggested_quantity=self.base_quantity)
             self.events_queue.put(signal)
             self.invested = True
         self.bars += 1
    def calculate_signals(self, event):
        if (event.type == EventType.BAR and event.ticker in self.tickers):
            # print("what type of price is in the event", event.adj_close_price, type(event.adj_close_price))
            # print("Our dataframe looks like this ", self.prices_df)
            self.prices_df = self.prices_df.append(
                {event.ticker: event.adj_close_price}, ignore_index=True)

            # self.prices_df[self.bars] = event.adj_close_price
            if self.bars == 0:
                print(self.prices_df)
                print("printeing the invested dictionary")
                for key, value in self.invested.items():
                    print(key, value)
            # if we have enough bars for the third window
            if self.bars > self.third_window + 1:
                # We only interested in monthly trading
                if self.bars % self.trade_freq == 0:
                    # print(self.prices_df.tail(5))
                    # calculate the 1 month, 3 month, 6 month returns
                    # current_price = self.prices_df.iloc[-1][ticker]
                    returns_dict = {}
                    for ticker in tickers:
                        # now we don't want to calculate returns for the risk free asset
                        if ticker not in [self.risk_free]:
                            current_price = self.prices_df[ticker].iloc[-1]
                            one_month = (
                                current_price - self.prices_df[ticker].iloc[
                                    -1 - self.first_window]) / current_price
                            three_month = (
                                current_price - self.prices_df[ticker].iloc[
                                    -1 - self.second_window]) / current_price
                            six_month = (
                                current_price - self.prices_df[ticker].iloc[
                                    -1 - self.third_window]) / current_price

                            returns_dict[ticker] = np.mean(
                                [one_month, three_month, six_month])

                    # logic now:  buy the asset with the max momo score when we are not invested
                    best_perfomer = max(returns_dict, key=returns_dict.get)
                    # print(best_perfomer)
                    if returns_dict[best_perfomer] > 0 and not self.invested[
                            best_perfomer]:
                        for investment in getKeysByValue(self.invested, True):
                            #     sell everything that we own
                            print("SELLING %s: %s" % (investment, event.time))
                            signal = SignalEvent(
                                investment,
                                "SLD",
                                suggested_quantity=self.base_quantity)
                            self.events_queue.put(signal)
                            self.invested[investment] = False

                        print("LONG %s: %s " % (best_perfomer, event.time))
                        signal = SignalEvent(
                            best_perfomer,
                            "BOT",
                            suggested_quantity=self.base_quantity)
                        self.events_queue.put(signal)
                        self.invested[best_perfomer] = True

                    #     Othrewise buy bonds if we dont own them already
                    else:
                        if self.invested[self.risk_free] == False:
                            for investment in getKeysByValue(
                                    self.invested, True):
                                #     sell everything that we own
                                print("SELLING %s: %s" %
                                      (investment, event.time))
                                signal = SignalEvent(
                                    investment,
                                    "SLD",
                                    suggested_quantity=self.base_quantity)
                                self.events_queue.put(signal)
                                self.invested[investment] = False

                            print("LONG %s: %s " %
                                  (self.risk_free, event.time))
                            signal = SignalEvent(
                                self.risk_free,
                                "BOT",
                                suggested_quantity=self.base_quantity)
                            self.events_queue.put(signal)
                            self.invested[self.risk_free] = True

            self.bars += 1
Example #7
0
    def calculate_signals(self, event):
        if (event.type in [EventType.BAR, EventType.TICK]
                and event.ticker in self.tickers
                # and self._end_of_month_trading_calendar(event.time)
            ):
            self.bars += 1
            self._set_correct_time_and_price(event)

            #  IF IT IS THE INDEX, THEN WE ONLY USE TO CALCULATE THE 200DAY MOVING AVERAGE
            if event.ticker == self.index_ticker:
                self.index_prices.append(event.adj_close_price)
                if len(self.index_prices) == self.index_dma_window:
                    # close = self.index_prices[-1]
                    # are_we_above = self.index_prices[-1] > np.mean(self.index_prices)
                    self.index_dma = self.index_prices[-1] > np.mean(
                        self.index_prices)

            # ticker = event.ticker
            # add closing prices to prices queue
            self.ticker_bars[event.ticker].append(event.adj_close_price)
            self.ticker_bars_unadj[event.ticker].append(event.close_price)

            # add todays prices prices and yesterdays prices
            # first we move the old price
            # self.high_lows[event.ticker]['yes_high'] = self.high_lows[event.ticker]['today_high']
            # self.high_lows[event.ticker]['yes_close'] = self.high_lows[event.ticker]['today_low']
            # today_high = event.high_price
            # today_high =

            self.high_lows[event.ticker]['today_high'] = int(
                event.high_price * event.adj_close_price / event.close_price)
            self.high_lows[event.ticker]['today_low'] = int(
                event.low_price * event.adj_close_price / event.close_price)

            todays_high = self.high_lows[event.ticker]['today_high']
            todays_low = self.high_lows[event.ticker]['today_low']

            if len(self.ticker_bars_unadj[event.ticker]) > 1:
                yesterdays_close = self.ticker_bars[event.ticker][-2]

                true_range = np.max([todays_high, yesterdays_close]) - np.min(
                    [todays_low, yesterdays_close])
                self.true_range[event.ticker].append(true_range)

                if len(self.true_range[event.ticker]) >= 20:
                    queue_of_tr = pd.Series(self.true_range[event.ticker])
                    atr_series = queue_of_tr.ewm(
                        span=20, min_periods=self.atr_period).mean()
                    self.atr[event.ticker] = atr_series

            # can only trade if all tickers have more than 90 days
            enough_days = True

            valid_tickers_for_day = self.valid_tickers(self.time)
            # todo here is where we check the burn in.  Logic needs changing otherwise

            count_incomplete_tickers = 0

            for ticker in valid_tickers_for_day:
                if len(self.ticker_bars[ticker]) < self.window or len(
                        self.ticker_bars[ticker]) < self.sma_days_for_stocks:
                    count_incomplete_tickers += 1
                    enough_days = False
                    # if not enough_days:
                    # 	break
            print("we do not have full window data and sma days for: ",
                  count_incomplete_tickers, "tickers")

            if enough_days:
                number_of_stocks_prices_seen = np.sum(
                    self.latest_prices > -1.0)
                # todo threshold only needs to be calculated once per day
                # todo the entire valid tickers could be calculated outside the strategy
                # todo it could be calculated in run and therefore speed it all up.
                threshold = self.number_of_valid_ticks_on_day(self.time)

            if enough_days and event.time.weekday(
            ) == 2 and number_of_stocks_prices_seen >= threshold:
                """calculate momentums"""

                # momentums = pd.DataFrame(self.tickers)
                momenta = {}
                for ticker in valid_tickers_for_day:
                    # closing_prices = list(self.ticker_bars[ticker])
                    closing_prices = list(
                        itertools.islice(
                            self.ticker_bars[ticker],
                            self.sma_days_for_stocks - self.window,
                            self.sma_days_for_stocks))
                    momenta[ticker] = self.expo_momentum(closing_prices)

                # momenta_df = pd.DataFrame(list(momenta.items), columns=['Asset', 'Momentum'])
                # momenta_df = momenta_df.sort_values(by = 'Momentum')

                # remove the index ticker from the table as we won't buy that
                momenta.pop(self.index_ticker, None)

                # interested in top fifth best performing assets
                n = int((len(valid_tickers_for_day) - 1) / 5)

                top_n = {
                    key: momenta[key]
                    for key in sorted(momenta, key=momenta.get, reverse=True)
                    [:n]
                }

                top_assets = list(top_n.keys())
                """
				Do any stocks we own need to be sold?
				"""
                for stock in self.tickers_invested:
                    if self.tickers_invested[stock]:
                        """
						check if we need to sell this
						"""
                        """
						if stock not in top assets ---> SELL
						if stock is below 100DMA --> SELL
						if gap over 15% --> SELL
						
						we need to update the tables every wednesday.  Either we keep the table as part of a class.
						Or for every tick coming in we calculate and then trade.
						
						"""
                        if stock not in top_assets:
                            liquidate_signal = SignalEvent(stock, "EXIT")
                            self.events_queue.put(liquidate_signal)
                            self.tickers_invested[stock] = False
                        elif self.below_100_dma(self.ticker_bars[stock][-1],
                                                stock):
                            liquidate_signal = SignalEvent(stock, "EXIT")
                            self.events_queue.put(liquidate_signal)
                            self.tickers_invested[stock] = False
                        elif self.move_greater_than_15(stock):
                            liquidate_signal = SignalEvent(stock, "EXIT")
                            self.events_queue.put(liquidate_signal)
                            self.tickers_invested[stock] = False
                """
				can we buy any stocks
				only if the index is above the 200DMA
				and if the stock is above 100DMA 
				and no move larger than 15%
				go through the top momentum list.  if we do not own buy until we run out of cash                
				"""
                if self.index_dma:
                    for ticker in top_assets:
                        if not self.below_100_dma(self.ticker_bars[ticker][-1], ticker) \
                          and not self.move_greater_than_15(ticker) \
                          and not self.tickers_invested[ticker]:
                            size = int(self.atr[ticker].iloc[-1])
                            long_signal = SignalEvent(ticker, "BOT", size)
                            self.events_queue.put(long_signal)

                            self.tickers_invested[ticker] = True
                """
				rebalance if its a second wednesday 
				what is the target size and what is the currents size of the position.
				if the difference is too much rebalance 
				
				go through all the assets with booleans. And then place orders to buy.  The position sizer will see its a rebalance
				then          
				"""
                if self.is_second_wed(event.time):
                    for stock in self.tickers_invested:
                        if self.tickers_invested[stock]:
                            size = int(self.atr[stock].iloc[-1])

                            long_signal = SignalEvent(stock, "BOT", size)
                            self.events_queue.put(long_signal)
Example #8
0
    def calculate_signals(self, event):
        if (event.type in [EventType.BAR, EventType.TICK]
                and event.ticker in self.tickers):
            no_invested = 0
            for key in self.tickers_invested:
                if self.tickers_invested[key]:
                    no_invested += 1
            if no_invested > 1:
                print("**************")
                print("INVESTED IN", no_invested, "ASSETS")
                print("**************")
            elif no_invested == 0 and self.bars > self.third_window:
                print("**************")
                print("EMPTY PORTFOLIO")
                print("**************")
            # if self.tickers_invested

            # append the price to the momo queue this might be WRONG!!!
            self.ticker_bars[event.ticker].append(event.adj_close_price)

            # this assumes an equal amount of bars in each input
            # if self.bars > (len(self.tickers) * self.third_window) + 1:
            can_trade = True
            for ticker in self.ticker_bars:
                if len(self.ticker_bars[ticker]) < self.third_window:
                    can_trade = False
            # now we have six months of prices in our bars
            # we create a dictionary with the mean returns over lookback periods
            #
            if can_trade:
                rank_assets = {}
                # risky_assets =
                for ticker in self.tickers:
                    if ticker != self.safe_asset:
                        current_price = self.ticker_bars[ticker][-1]
                        one_month = (current_price - self.ticker_bars[ticker][
                            -1 - self.first_window]) / current_price
                        three__month = (current_price - self.ticker_bars[
                            ticker][-1 - self.second_window]) / current_price
                        six_month = (current_price - self.ticker_bars[ticker][
                            -1 - self.third_window + 1]) / current_price

                        accel_momo = np.mean(
                            [one_month, three__month, six_month])
                        rank_assets[ticker] = accel_momo

                # NOW WE KNOW WHICH ASSET TO BUY DO WE BUY IT ON THE NEXT DAY??

                # action at end of the month
                if self._end_of_month(event.time):
                    if self.asset_to_invest_in[
                            0] is None or self.asset_to_invest_in[
                                0].month != event.time.month:
                        asset_to_trade = self.which_asset_to_invest(
                            rank_assets)
                        print(asset_to_trade, "IS THE ASSET TO OWN",
                              event.time)
                        self.asset_to_invest_in = (event.time, asset_to_trade)

                    ticker = event.ticker
                    # and we are not invested
                    if ticker == self.asset_to_invest_in[
                            1] and not self.tickers_invested[ticker]:
                        print("LONG %s: %s" % (ticker, event.time))
                        long_signal = SignalEvent(
                            ticker,
                            "BOT",
                            suggested_quantity=self.base_quantity)
                        self.events_queue.put(long_signal)
                        self.tickers_invested[ticker] = True
                    elif ticker != self.asset_to_invest_in[
                            1] and self.tickers_invested[ticker]:
                        print("EXIT %s: %s" % (ticker, event.time))
                        liquidate_signal = SignalEvent(ticker, "EXIT")
                        self.events_queue.put(liquidate_signal)
                        self.tickers_invested[ticker] = False
            # else if there is an asset we should be in.
            elif self.asset_to_invest_in[1] is not None:
                for key in self.tickers_invested:
                    if self.tickers_invested[
                            key] and key != self.asset_to_invest_in[
                                1] and key == event.ticker:
                        print("We should not be invested EXITING", key,
                              "NOT equal to", self.asset_to_invest_in[1])
                        print("EXIT %s: %s" % (event.ticker, event.time))
                        liquidate_signal = SignalEvent(event.ticker, "EXIT")
                        self.events_queue.put(liquidate_signal)
                        self.tickers_invested[event.ticker] = False
                    elif not self.tickers_invested[
                            key] and key == self.asset_to_invest_in[
                                1] and key == event.ticker:
                        print("LONG %s: %s" % (ticker, event.time))
                        long_signal = SignalEvent(
                            ticker,
                            "BOT",
                            suggested_quantity=self.base_quantity)
                        self.events_queue.put(long_signal)
                        self.tickers_invested[ticker] = True

            self.bars += 1
            """