def get_tweets(self, ticker, search_terms=None): """Get tweets about a ticker :param ticker: :param search_terms: optional additional search term :return: string consisting of text from tweets """ if not search_terms or search_terms is None: query = "{} stock".format(ticker) else: query = "{} stock {}".format(ticker, search_terms) results = self.api.GetSearch(query, result_type="recent", count=100) result_dicts = [ dict(created_at=time_formatter(float( result.created_at_in_seconds)), user=result.user.name, text=result.text) for result in results if "RT" not in result.text ] texts = [res["text"] for res in result_dicts] text = "\n\n".join(texts) return text
def sec_filings(self, barcount=64, poolsize=5, form_type="8-K", backdate=None): """Return tradeable asets with recent SEC filings. :param barcount: :param poolsize: :param form_type: :param backdate: :return: """ if not self.edgar_token or self.edgar_token is None: raise NotImplementedError if not backdate or backdate is None: # backdate = time_formatter(time.time() - 604800, time_format="%Y-%m-%d") # using a longer window only for debugging purposes -- just to make sure I have results quickly backdate = time_formatter(time.time() - (604800 * 26), time_format="%Y-%m-%d") date = time_formatter(time.time(), time_format="%Y-%m-%d") # Filter the assets down to just those on NASDAQ. active_assets = self.get_assets() assets = self.extract_tradeable_assets(active_assets) print("Going through assets looking for firms with recent SEC filings") for i in assets: self.get_filings(i, backdate=backdate, date=date, form_type=form_type) if len(self.recent_filings.keys()) >= poolsize: break else: continue self.tradeable_assets_by_filings(barcount) return self.assets_by_filing
def get_filings(self, asset, backdate, date, form_type="8-K"): """Given a trading entity, get SEC filings in the date range. :param asset: :param backdate: :param date: :param form_type: :return: """ filings = self.ei.get_sec_filings(asset.symbol, backdate, date, form_type=form_type) # If none are found, lengthen the lookback window a couple times if filings["total"] is 0: print( "No recent filings found for {}. Looking back 2 weeks".format( asset.symbol)) backdate = time_formatter(time.time() - (604800 * 2), time_format="%Y-%m-%d") filings = self.ei.get_sec_filings(asset.symbol, backdate, date, form_type=form_type) if filings["total"] is 0: print("No filings found. Looking back 4 weeks") backdate = time_formatter(time.time() - (604800 * 4), time_format="%Y-%m-%d") filings = self.ei.get_sec_filings(asset.symbol, backdate, date, form_type=form_type) if filings["total"] > 0: print("\tAdded:", asset.symbol, " symbols:", len(self.recent_filings.keys()) + 1) filings = json.dumps(filings) self.recent_filings[asset.symbol] = filings
def get_vzo_dmi_apz(self, ticker, backdate=None): """Given a ticker symbol and a historic, calculate various indicators from then to now. Currently, VZO, DMI and APZ oscillator are implemented. :param ticker: a stock ticker symbol :param backdate: start of the historic data lookup period. If none, defaults to the last 13 weeks (1 quarter) :return: dataframe built from barset objects, including indicators """ if not ticker or ticker is None: raise ValueError("Invalid ticker value") if not backdate or backdate is None: backdate = time_formatter(time.time() - (604800 * 13)) bars = self.get_bars(ticker, backdate) data = set_candlestick_df(bars) print(data["close"].iloc[-1], data["close"].iloc[-2], data["close"].iloc[-3]) # get VZO - bullish trend range 5-40%; oversold - -40%; extremely oversold -60% try: vzo = self.get_vzo(data) except IndicatorException: raise IndicatorException else: pass # get DMI - buy sign when + line crosses over - line try: dmi = self.get_dmi(data) except IndicatorException: raise IndicatorException else: pass # get APZ - volatility indicator try: apz = self.get_apz(data) except IndicatorException: raise IndicatorException else: pass data["ticker"] = ticker data["vzo"] = vzo data["dmi_p"] = dmi["DI+"] data["dmi_m"] = dmi["DI-"] data["apz_u"] = apz["UPPER"] data["apz_l"] = apz["LOWER"] return data
def get_edgar_signals(self): """Loop through tickers and append EDGAR signals to that ticker's dataframe""" if not self.dataframe or self.dataframe is None: raise NotImplementedError( "Dataframe should only be none if AssetSelector is using it") for ticker in self.dataframe.keys(): fdate = self.dataframe[ticker]["time"].iloc[-7].strftime( "%Y-%m-%d") tdate = time_formatter(time.time(), time_format="%Y-%m-%d") self.edgar_scores[ticker] = self.calculate_edgar_signal( ticker, fdate, tdate) return self.edgar_scores
def get_macd_mfi_stoch(self, ticker, backdate=None): """Given a ticker symbol and a historic, calculate various indicators from then to now. Currently, MACD, MFI and stochastic oscillators are implemented. :param ticker: a stock ticker symbol :param backdate: start of the historic data lookup period. If none, defaults to the last 13 weeks (1 quarter) :return: dataframe built from barset objects, including indicators """ if not ticker or ticker is None: raise ValueError("Invalid ticker value") if not backdate or backdate is None: backdate = time_formatter(time.time() - (604800 * 13)) bars = self.get_bars(ticker, backdate) data = set_candlestick_df(bars) # get MACD try: macd = self.get_macd(data) except IndicatorException: raise IndicatorException else: _macds = macd["MACD"] _signals = macd["SIGNAL"] # get money flow index try: mfi = self.get_mfi(data) except IndicatorException: raise IndicatorException else: pass # get stochastic oscillator try: stoch = self.get_stoch(data) except IndicatorException: raise IndicatorException else: pass data["ticker"] = ticker data["macd"] = _macds data["signal"] = _signals data["mfi"] = mfi data["stoch"] = stoch return data
def tradeable_assets_by_filings(self, barcount=64): """Populate tradeable assets based on discovered SEC filings. :return: """ for i in self.recent_filings.keys(): # I think I need my original 13 week window here for consistency with get_assets_by_candlestick_pattern backdate = time_formatter(time.time() - (604800 * 13)) barset = self.get_barset(i.symbol, "1D", backdate) if num_bars(barset[i.symbol], barcount) is False: continue df = self.extract_bar_data(barset, i.symbol) self.assets_by_filing[i.symbol] = df
def get_bars(self, ticker, backdate=None): """Get bars for a ticker symbol :param ticker: a stock ticker symbol :param backdate: start of the historic data lookup period. If none, defaults to the last 13 weeks (1 quarter) :return: dataframe built from barset objects, including indicators """ if not ticker or ticker is None: raise ValueError("Invalid ticker value") if not backdate or backdate is None: backdate = time_formatter(time.time() - (604800 * 13)) bars = None try: bars = self.api.get_barset(ticker, "1D", after=backdate)[ticker] except HTTPError: print("Retrying...") time.sleep(3) try: bars = self.api.get_barset(ticker, "1D", after=backdate)[ticker] except HTTPError: raise HTTPError finally: return bars
def compare_macd_vmacd(self, ticker, backdate=None): """Compare different MACD indicators.""" if not ticker or ticker is None: raise ValueError("Invalid ticker value") if not backdate or backdate is None: backdate = time_formatter(time.time() - (604800 * 13)) bars = self.get_bars(ticker, backdate) data = set_candlestick_df(bars) # get MACD try: macd = self.get_macd(data) except IndicatorException: raise IndicatorException else: _macds = macd["MACD"] _signals = macd["SIGNAL"] # get VW_MACD try: vwmacd = self.get_vwmacd(data) except IndicatorException: raise IndicatorException else: _vmacds = vwmacd["MACD"] _vsignals = vwmacd["SIGNAL"] data["ticker"] = ticker data["macd"] = _macds data["signal"] = _signals data["vwmacd"] = _vmacds data["vwsignal"] = _vsignals return data
def __init__(self, alpaca_api_interface, backdate=None, edgar_token=None): if not alpaca_api_interface or alpaca_api_interface is None: raise ValueError("Alpaca API interface instance required.") if not backdate or backdate is None: backdate = time_formatter(time.time() - (604800 * 13)) self.api = alpaca_api_interface self.backdate = backdate self.edgar_token = None if edgar_token is not None: self.edgar_token = edgar_token self.ei = EdgarInterface(self.edgar_token) self.raw_assets = None self.tradeable_assets = None self.bulls = dict() self.bears = dict() self.recent_filings = dict() self.assets_by_filing = dict() self.populate()
def cluster_prep(self, ticker, backdate=None): """Compare different MACD indicators.""" if not ticker or ticker is None: raise ValueError("Invalid ticker value") if not backdate or backdate is None: backdate = time_formatter(time.time() - (604800 * 13)) bars = self.get_bars(ticker, backdate) data = set_candlestick_df(bars) # get Bollinger bands try: bbands = self.get_bbands(data) except IndicatorException: raise IndicatorException else: _bb_up = bbands["BB_UPPER"] _bb_mid = bbands["BB_MIDDLE"] _bb_low = bbands["BB_LOWER"] # get MACD try: macd = self.get_macd(data) except IndicatorException: raise IndicatorException else: _macds = macd["MACD"] _signals = macd["SIGNAL"] # get VW_MACD try: vwmacd = self.get_vwmacd(data) except IndicatorException: raise IndicatorException else: _vmacds = vwmacd["MACD"] _vsignals = vwmacd["SIGNAL"] # get money flow index try: mfi = self.get_mfi(data) except IndicatorException: raise IndicatorException else: pass # get stochastic oscillator try: stoch = self.get_stoch(data) except IndicatorException: raise IndicatorException else: pass # get VZO - bullish trend range 5-40%; oversold - -40%; extremely oversold -60% try: vzo = self.get_vzo(data) except IndicatorException: raise IndicatorException else: pass # get ADX - trending if > 20; > 40 is strong trend; > 50 is very strongtrend # Welp this uses the broken indicator, therefore it is also broken. # try: # adx = self.get_adx(data) # except IndicatorException: # raise IndicatorException # else: # pass # get APZ - volatility indicator -- might be useful in sentiment comparison try: apz = self.get_apz(data) except IndicatorException: raise IndicatorException else: pass # get DMI - buy sign when + line crosses over - line try: dmi = TA.DMI(data) except IndicatorException: raise IndicatorException else: pass # ¯\_(ツ)_/¯ seems to be a bug in finta DMI implementation - returning lists of NaN # TODO: investigate - https://github.com/bbeale/finta # Seems to be appending the values I am expecting it to return directly to my dataframe instead of returning them. # Hmm... # data["dmi_p"] = dmi["DMp"] # data["dmi_m"] = dmi["DMm"] # data["ticker"] = ticker data["bb_up"] = _bb_up data["bb_mid"] = _bb_mid data["bb_low"] = _bb_low data["macd"] = _macds data["signal"] = _signals data["vwmacd"] = _vmacds data["vwsignal"] = _vsignals data["mfi"] = mfi data["stoch"] = stoch data["vzo"] = vzo # data["adx"] = adx data["apz_u"] = apz["UPPER"] data["apz_l"] = apz["LOWER"] # Percent changes data["bb_up_ptc"] = _bb_up.pct_change() data["bb_mid_ptc"] = _bb_mid.pct_change() data["bb_low_ptc"] = _bb_low.pct_change() data["macd_ptc"] = _macds.pct_change() data["signal_ptc"] = _signals.pct_change() data["vwmacd_ptc"] = _vmacds.pct_change() data["vwsignal_ptc"] = _vsignals.pct_change() data["mfi_ptc"] = mfi.pct_change() data["stoch_ptc"] = stoch.pct_change() data["vzo_ptc"] = vzo.pct_change() # data["adx_ptc"] = adx.pct_change() data["apz_u_ptc"] = apz["UPPER"].pct_change() data["apz_l_ptc"] = apz["LOWER"].pct_change() return data