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
def calculate_signals(self, event): # Applies SMA to first ticker ticker = self.tickers[0] if event.type == EventType.BAR and event.ticker == ticker: # Add latest adjusted closing price to the # short and long window bars price = event.adj_close_price / float(PriceParser.PRICE_MULTIPLIER) self.lw_bars.append(price) if self.bars > self.long_window - self.short_window: self.sw_bars.append(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" % event.time) signal = SignalEvent(ticker, "BOT", self.base_quantity) self.events_queue.put(signal) self.invested = True elif short_sma < long_sma and self.invested: print("SHORT: %s" % event.time) signal = SignalEvent(ticker, "SLD", self.base_quantity) self.events_queue.put(signal) self.invested = False self.bars += 1
def calculate_signals(self, event): if (event.type in [EventType.BAR, EventType.TICK] and self._end_of_month(event.time)): ticker = event.ticker if self.tickers_invested[ticker]: liquidate_signal = SignalEvent(ticker, "EXIT") self.evert_queue.put(liquidate_signal) long_signal = SignalEvent(ticker, "BOT") self.evert_queue.put(long_signal) self.tickers_invested[ticker] = True
def go_short_units(self): """ Go short the appropriate number of "units" of the portfolio to open a new position or to close out a long position. """ for i, ticker in enumerate(self.tickers): if self.weights[i] < 0.0: self.events_queue.put( SignalEvent(ticker, "BOT", int(floor(-1.0 * self.qty * self.weights[i])))) else: self.events_queue.put( SignalEvent(ticker, "SLD", int(floor(self.qty * self.weights[i]))))
def calculate_signals(self, event): """ For a particular received BarEvent, determine whether it is the end of the month (for that bar) 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_month(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
def calculate_signals(self, event): ticker = self.tickers[0] if event.type in [EventType.BAR, EventType.TICK ] and event.ticker == ticker: if not self.invested and self.ticks == 0: signal = SignalEvent(ticker, "BOT") self.events_queue.put(signal) self.invested = True self.ticks += 1
def calculate_signals(self, event): """ Calculate the signals for the strategy. """ if event.type == EventType.SENTIMENT: ticker = event.ticker if ticker != "SPY": # Long signal if (self.invested[ticker] is False and event.sentiment >= self.sent_buy): print("LONG %s at %s" % (ticker, event.timestamp)) self.events_queue.put(SignalEvent(ticker, "BOT", self.qty)) self.invested[ticker] = True # Close signal if (self.invested[ticker] is True and event.sentiment <= self.sent_sell): print("CLOSING LONG %s at %s" % (ticker, event.timestamp)) self.events_queue.put(SignalEvent(ticker, "SLD", self.qty)) self.invested[ticker] = False
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 test_create_order_from_signal_basic_check(self): """ Tests the "_create_order_from_signal" method as a basic sanity check. """ signal_event = SignalEvent("MSFT", "BOT") order = self.portfolio_handler._create_order_from_signal(signal_event) self.assertEqual(order.ticker, "MSFT") self.assertEqual(order.action, "BOT") self.assertEqual(order.quantity, 0)
def test_on_signal_basic_check(self): """ Tests the "on_signal" method as a basic sanity check. """ signal_event = SignalEvent("MSFT", "BOT") self.portfolio_handler.on_signal(signal_event) ret_order = self.portfolio_handler.events_queue.get() self.assertEqual(ret_order.ticker, "MSFT") self.assertEqual(ret_order.action, "BOT") self.assertEqual(ret_order.quantity, 100)
def calculate_signals(self, event): if (event.type == EventType.BAR and event.ticker == self.ticker): exit_position = False signal = event.signal[event.signal['symbol'] == event.ticker] self.signals = self.signals.append(signal) if self.invested: # exit_position = self.expired_not_profit() if not exit_position and len(self.signals) > 2: two_ago = self.signals.iloc[-2] one_ago = self.signals.iloc[-1] exit_position = ( (one_ago['sma'] < one_ago['bb_middleband']) and (two_ago['sma'] > two_ago['bb_middleband']) # and len(went_up) < 1 ) if exit_position: print('SMA exit') if not exit_position: entry = self.signals.loc[ self.signals['date'] >= self.entry_time] # if entry['close'][0] < signal['trailing_stop'][0] and signal['adx'][0] > 10: if signal['close'][0] < entry['trailing_stop'].max( ) and signal['adx'][0] > 10: exit_position = True print('Trailing exit - ' + str(signal['adx'][0])) # Trading signals based on moving average cross if signal['buy'][0] == 1 and not self.invested: print("LONG %s: %s" % (self.ticker, event.time)) self.entry_time = signal['date'][0] signal_event = SignalEvent( self.ticker, "BOT", suggested_quantity=self.base_quantity) self.events_queue.put(signal_event) self.invested = True elif (signal['sell'][0] == 1 or exit_position) and self.invested: print("SHORT %s: %s" % (self.ticker, event.time)) signal_event = SignalEvent( self.ticker, "SLD", suggested_quantity=self.base_quantity) self.events_queue.put(signal_event) self.invested = False
def calculate_signals(self, event): """ Calculate the intraday machine learning prediction strategy. """ if event.type == EventType.BAR: self._update_current_returns(event) self.minutes += 1 # Allow enough time to pass to populate the # returns feature vector if self.minutes > (self.lags + 2): pred = self.model.predict(self.cur_returns.reshape((1, -1)))[0] # Long only strategy if not self.invested and pred == 1: print("LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "BOT", self.qty)) self.invested = True if self.invested and pred == -1: print("CLOSING LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "SLD", self.qty)) self.invested = False
def calculate_signals(self, event): """ Calculate the Kalman Filter strategy. """ if event.type == EventType.BAR: self._set_correct_time_and_price(event) # Only trade if we have both observations if all(self.latest_prices > -1.0): # Create the observation matrix of the latest prices # of TLT and the intercept value (1.0) as well as the # scalar value of the latest price from IEI F = np.asarray([self.latest_prices[0], 1.0]).reshape((1, 2)) y = self.latest_prices[1] # The prior value of the states \theta_t is # distributed as a multivariate Gaussian with # mean a_t and variance-covariance R_t if self.R is not None: self.R = self.C + self.wt else: self.R = np.zeros((2, 2)) # Calculate the Kalman Filter update # ---------------------------------- # Calculate prediction of new observation # as well as forecast error of that prediction yhat = F.dot(self.theta) et = y - yhat # Q_t is the variance of the prediction of # observations and hence \sqrt{Q_t} is the # standard deviation of the predictions Qt = F.dot(self.R).dot(F.T) + self.vt sqrt_Q = np.sqrt(Qt) # The posterior value of the states \theta_t is # distributed as a multivariate Gaussian with mean # m_t and variance-covariance C_t At = self.R.dot(F.T) / Qt self.theta = self.theta + At.flatten() * et self.C = self.R - At * F.dot(self.R) # Only trade if days is greater than a "burn in" period if self.days > 1: # If we’re not in the market... if self.invested is None: if e < -sqrt_Q: # Long Entry print("LONG: %s" % event.time) self.cur_hedge_qty = int( floor(self.qty * self.theta[0])) self.events_queue.put( SignalEvent(self.tickers[1], "BOT", self.qty)) self.events_queue.put( SignalEvent(self.tickers[0], "SLD", self.cur_hedge_qty)) self.invested = "long" elif e > sqrt_Q: # Short Entry print("SHORT: %s" % event.time) self.cur_hedge_qty = int( floor(self.qty * self.theta[0])) self.events_queue.put( SignalEvent(self.tickers[1], "SLD", self.qty)) self.events_queue.put( SignalEvent(self.tickers[0], "BOT", self.qty)) self.invested = "short" # If we are in the market... if self.invested is not None: if self.invested == "long" and e > -sqrt_Q: print("CLOSING LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[1], "SLD", self.qty)) self.events_queue.put( SignalEvent(self.tickers[0], "BOT", self.cur_hedge_qty)) self.invested = None elif self.invested == "short" and e < sqrt_Q: print("CLOSING SHORT: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[1], "BOT", self.qty)) self.events_queue.put( SignalEvent(self.tickers[0], "SLD", self.cur_hedge_qty)) self.invested = None
if event.type == EventType.BAR: self._update_current_returns(event) self.minutes += 1 gap = event.ask - event.bid # Allow enough time to pass to populate the # returns feature vector if self.minutes > (self.lags + 2) and event.close_price > 0: #>0 por seguridad pred = self.modelpkl.predict(self.cur_returns.reshape((1, -1)))[0] # Long only strategy if self.invested == "NONE" and gap <= 200000: if pred > self.toplimit: self.qty = int(round(30000/(event.close_price/float( PriceParser.PRICE_MULTIPLIER)),0)-1.0) print("LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "buy", self.qty) ) self.prev_invested = "NONE" self.invested = "LONG" self.contador = 0 #self.entry_price = event.close_price/float( # PriceParser.PRICE_MULTIPLIER) elif pred < self.botlimit: self.qty = int(round(30000/(event.close_price/float( PriceParser.PRICE_MULTIPLIER)),0)-1.0) print("SHORT: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "sell", self.qty) ) self.prev_invested = "NONE" self.invested = "SHORT"
def calculate_signals(self, event): """ Calculate the Kalman Filter strategy. """ if event.type == EventType.BAR: self._set_correct_time_and_price(event) idx = self.tickers.index(event.ticker) pair_idx = idx // 2 # Only trade if we have both observations data = self.trader_data[pair_idx] if not all(data['latest_prices'] > -1.0): return F = np.asarray([data['latest_prices'][0], 1.0]).reshape((1, 2)) y = data['latest_prices'][1] if data['R'] is not None: data['R'] = data['C'] + data['wt'] else: data['R'] = np.zeros((2, 2)) yhat = F.dot(data['theta']) et = y - yhat Qt = F.dot(data['R']).dot(F.T) + data['vt'] sqrt_Qt = np.sqrt(Qt) At = data['R'].dot(F.T) / Qt data['theta'] = data['theta'] + At.flatten() * et data['C'] = data['R'] - At * F.dot(data['R']) investment_per_pair = self.investment_per_pair # if pair_idx == self.num_pairs - 1: # investment_per_pair *= 0 # continue if self.days > 1: # If we're not in the market... if data['invested'] is None: if et < -factorA * sqrt_Qt: # Long Entry # print("LONG: %s" % event.time) data['qty'] = floor(investment_per_pair / data['latest_prices'][1]) data['cur_hedge_qty'] = floor(investment_per_pair / data['latest_prices'][0]) # data['cur_hedge_qty'] = int( # floor(data['qty'] * data['theta'][0])) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2 + 1], "BOT", data['qty'])) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2], "SLD", data['cur_hedge_qty'])) data['invested'] = "long" elif et > factorA * sqrt_Qt: # Short Entry # print("SHORT: %s" % event.time) data['qty'] = floor(investment_per_pair / data['latest_prices'][1]) data['cur_hedge_qty'] = floor(investment_per_pair / data['latest_prices'][0]) # data['cur_hedge_qty'] = int(floor(data['qty'] * data['theta'][0])) # self.cur_hedge_qty = int( # floor(self.qty * self.theta[0])) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2 + 1], "SLD", data['qty'])) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2], "BOT", data['cur_hedge_qty'])) data['invested'] = "short" # If we are in the market... if data['invested'] is not None: if data['invested'] == 'long' and et > -factorC * sqrt_Qt: # print("CLOSING LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2 + 1], "SLD", data['qty'])) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2], "BOT", data['cur_hedge_qty'])) data['invested'] = None elif data['invested'] == "short" and et < factorC * sqrt_Qt: # print("CLOSING SHORT: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2 + 1], "BOT", data['qty'])) self.events_queue.put( SignalEvent(self.tickers[pair_idx * 2], "SLD", data['cur_hedge_qty'])) data['invested'] = None
def calculate_signals(self, event): if self.RF == "RFR": """ Calculate the intraday machine learning prediction strategy. """ if event.type == EventType.BAR: self._update_current_returns(event) self.minutes += 1 # Allow enough time to pass to populate the # returns feature vector #if self.minutes > (self.lags + 2): # original if self.minutes > (self.lags - 1): # chk = True if all(x == self.skip for x in self.delta): chk = True else: chk = False try: f = open( self.current_directory + "/" + "Discontinuity.txt", "r") f.close() f = open( self.current_directory + "/" + "Discontinuity.txt", "a") f.write(str(self.cur_time) + "\n") f.close() except IOError: f = open( self.current_directory + "/" + "Discontinuity.txt", "w+") f.write(str(self.cur_time) + "\n") f.close() if chk: if self.poly >= 2: cont = 0 for i in range(0, self.lags): for j in range(i, self.lags): self.add_returns[cont] = self.cur_returns[ i] * self.cur_returns[j] cont += 1 if self.poly == 3: for i in range(0, self.lags): for j in range(i, self.lags): for k in range(j, self.lags): self.add_returns[ cont] = self.cur_returns[ i] * self.cur_returns[ j] * self.cur_returns[k] cont += 1 cur_returns = np.concatenate( (self.cur_returns, self.add_returns)) else: cur_returns = self.cur_returns try: f = open(self.current_directory + "/" + "test.txt", "r") f.close() f = open(self.current_directory + "/" + "test.txt", "a") f.write(str(event.time) + str(cur_returns) + "\n") f.close except IOError: f = open(self.current_directory + "/" + "test.txt", "w+") f.write(str(event.time) + str(cur_returns) + "\n") f.close pred = self.modelpkl.predict( cur_returns.reshape((1, -1)))[0] #print(event.time, pred) try: f = open( self.current_directory + "/" + "pred_test.txt", "r") f.close() f = open( self.current_directory + "/" + "pred_test.txt", "a") f.write(str(event.time) + "_" + str(pred) + "\n") f.close except IOError: f = open( self.current_directory + "/" + "pred_test.txt", "w+") f.write(str(event.time) + "_" + str(pred) + "\n") f.close # current_price = event.close_price/float( # PriceParser.PRICE_MULTIPLIER) # Long only strategy if self.invested == "NONE": if pred > self.toplimit: self.qty = int( round( 30000 / (event.close_price / float(PriceParser.PRICE_MULTIPLIER)), 0) - 1.0) print("LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "BOT", self.qty)) self.invested = "LONG" self.contador = 0 #self.entry_price = event.close_price/float( # PriceParser.PRICE_MULTIPLIER) # elif pred < self.botlimit: # self.qty = int(round(30000/(event.close_price/float( # PriceParser.PRICE_MULTIPLIER)),0)-1.0) # print("SHORT: %s" % event.time) # self.events_queue.put( # SignalEvent(self.tickers[0], "SLD", self.qty) # ) # self.invested = "SHORT" # self.contador = 0 # #self.entry_price = event.close_price/float( # # PriceParser.PRICE_MULTIPLIER) elif self.invested == "LONG": self.contador += 1 # if current_price > self.entry_price: # print("CLOSING LONG: %s" % event.time) # self.events_queue.put( # SignalEvent(self.tickers[0], "SLD", self.qty) # ) # self.invested = "NONE" #if pred < self.botlimit: if self.contador == self.salida: print("CLOSING LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "SLD", self.qty)) self.invested = "NONE" # elif self.invested == "SHORT": # self.contador += 1 # # if current_price < self.entry_price: # # print("CLOSING LONG: %s" % event.time) # # self.events_queue.put( # # SignalEvent(self.tickers[0], "BOT", self.qty) # # ) # # self.invested = "NONE" # #if pred > self.toplimit: # if self.contador == self.salida: # print("CLOSING SHORT: %s" % event.time) # self.events_queue.put( # SignalEvent(self.tickers[0], "BOT", self.qty) # ) # self.invested = "NONE" elif self.RF == "RFC": """ Calculate the intraday machine learning prediction strategy. """ if event.type == EventType.BAR: self._update_current_returns(event) self.minutes += 1 # Allow enough time to pass to populate the # returns feature vector if self.minutes > (self.lags + 2): # chk = True if all(x == self.skip for x in self.delta): chk = True else: chk = False try: f = open( self.current_directory + "/" + "Discontinuity.txt", "r") f.close() f = open( self.current_directory + "/" + "Discontinuity.txt", "a") f.write(str(self.cur_time) + "\n") f.close() except IOError: f = open( self.current_directory + "/" + "Discontinuity.txt", "w+") f.write(str(self.cur_time) + "\n") f.close() if chk: pred = self.modelpkl.predict( self.cur_returns.reshape((1, -1)))[0] if self.invested == "NONE": if pred == 1: self.qty = int( round( 30000 / (event.close_price / float(PriceParser.PRICE_MULTIPLIER)), 0) - 1.0) print("LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "BOT", self.qty)) self.invested = "LONG" self.contador = 0 elif pred == -1: self.qty = int( round( 30000 / (event.close_price / float(PriceParser.PRICE_MULTIPLIER)), 0) - 1.0) print("SHORT: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "SLD", self.qty)) self.invested = "SHORT" self.contador = 0 elif self.invested == "LONG": self.contador += 1 if self.contador == self.salida: # if pred == -1: print("CLOSING LONG: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "SLD", self.qty)) self.invested = "NONE" elif self.invested == "SHORT": self.contador += 1 if self.contador == self.salida: # if pred == 1: print("CLOSING SHORT: %s" % event.time) self.events_queue.put( SignalEvent(self.tickers[0], "BOT", self.qty)) self.invested = "NONE"