def handle(self, *args, **options): print 'starting script' today_date = datetime.today().date() tomorrow_date = (datetime.today() + timedelta(days=1)).date() tickers_reporting_today = Ticker.objects.filter(earnings_announcement=today_date) tickers_reporting_tomorrow = Ticker.objects.filter(earnings_announcement=tomorrow_date) message_snippets = [] message_snippets.append("*Companies reporting earnings today:*") if not tickers_reporting_today: message_snippets.append("_none_") else: for t in tickers_reporting_today: message_snippets.append(" - %s (*%s*) : _%s_" % (t.company_name, t.ticker_symbol, t.services_for_ticker)) message_snippets.append("*Companies reporting earnings tomorrow* (%s):" % tomorrow_date.strftime("%a, %b %d, %Y")) if not tickers_reporting_tomorrow: message_snippets.append("_none_") else: for t in tickers_reporting_tomorrow: message_snippets.append(" - %s (*%s*) : _%s_" % (t.company_name, t.ticker_symbol, t.services_for_ticker)) message_to_post = "\n".join(message_snippets) post_message_to_slack(message_to_post) print message_to_post
def handle(self, *args, **options): print 'starting script' yesterday = (datetime.today() - timedelta(days=1)).date() articles_published_yesterday = Article.objects.filter(date_pub__year=yesterday.year,date_pub__month=yesterday.month, date_pub__day=yesterday.day) unique_urls = set([a.url for a in articles_published_yesterday]) article_count = len(unique_urls) message_snippets = [] message_snippets.append("*Articles recap for %s *" % yesterday.strftime('%a, %b %d, %Y')) # eg: Tue, May 12, 2015 message_snippets.append("articles published: %d" % article_count) if article_count > 0: ticker_symbols_list = [a.ticker.ticker_symbol for a in articles_published_yesterday] tickers_count = len(set(ticker_symbols_list)) # which tickers received the most coverage, across yesterday's articles? # use python's Counter to do the counting for us. https://docs.python.org/dev/library/collections.html#counter-objects most_common_tickers = [] tickers_frequency_counter = Counter(ticker_symbols_list) most_common = tickers_frequency_counter.most_common(15) # we'll pick at most the top 15 for ticker_popularity in most_common: ticker_symbol = ticker_popularity[0] count = ticker_popularity[1] # if count == 1, then this isn't so interesting. let's not bother including it if count==1: break most_common_tickers.append("%s (%d)" % (ticker_symbol, count)) most_common_tickers = ', '.join(most_common_tickers) # eg: AVAV (3), FB (2), AAPL (2) article_count_by_service = '' for s in Service.objects.all().order_by('pretty_name'): articles_for_service = [a for a in articles_published_yesterday if a.service==s] num_articles_for_service = len(set([a.url for a in articles_for_service])) if num_articles_for_service > 0: tickers_in_service_articles = set([a.ticker.ticker_symbol for a in articles_for_service]) tickers_in_service_articles = list(tickers_in_service_articles) tickers_in_service_articles.sort() article_count_by_service += "\n - %s : %d (%s)" % (s.pretty_name, num_articles_for_service, ', '.join(tickers_in_service_articles)) message_snippets.append("```tickers covered: %d" % tickers_count) if most_common_tickers: message_snippets.append("tickers with the most coverage: %s" % most_common_tickers) message_snippets.append('--------------') message_snippets.append("articles by service: %s" % article_count_by_service) message_snippets.append('```') message_to_post = "\n".join(message_snippets) post_message_to_slack(message_to_post)
def process_rules(): # find tickers that newly satisfy the threshold value # alert subscribers that follow any of those tickers # find tickers that satisfy the threshold value tickers_with_big_movement = Ticker.objects.filter( Q(daily_percent_change__gt=INTRADAY_THRESHOLD) | Q(daily_percent_change__lt=-1*INTRADAY_THRESHOLD)).order_by('ticker_symbol') # filter down to the ones that have hit the threshold for the first time today # create a receipt for each of these newly-detected big movers new_movers_receipts = [] for t in tickers_with_big_movement: matches_for_today = IntradayBigMovementReceipt.objects.filter(ticker=t, timestamp__gt=timezone.now().date()) if not matches_for_today: new_movers_receipts.append(IntradayBigMovementReceipt.create(t, t.daily_percent_change)) print 'newly-detected big movers: %d (%s)' % (len(new_movers_receipts), ', '.join([nmr.ticker.ticker_symbol for nmr in new_movers_receipts])) if len(new_movers_receipts) == 0: return # for each active subscriber, figure out which of the newly-detected big movers match his interests for subscriber in NotificationSubscriber.objects.filter(is_active=True): tickers_for_subscriber = [t.strip() for t in subscriber.tickers_csv.upper().split(',')] subscriber_services = [s.pretty_name.strip() for s in subscriber.services.all()] messages_for_subscriber = [] for r in new_movers_receipts: if r.ticker.ticker_symbol in tickers_for_subscriber: messages_for_subscriber.append(r.message) elif r.ticker.services_for_ticker: ticker_services = [s.strip() for s in r.ticker.services_for_ticker.split(',')] if set(subscriber_services) & set(ticker_services): messages_for_subscriber.append(r.message) if messages_for_subscriber: message_text = '```' + '\n'.join(messages_for_subscriber) + '```' post_message_to_slack(message_text=message_text, channel=subscriber.slack_handle, username='******', icon_emoji=':boom:') print 'alerted %s: %s' % (subscriber.slack_handle, message_text)
def handle(self, *args, **options): print 'starting script' # create a dictionary, keys = service pretty name, values = a list of tickers in that service tickers_by_service_pretty_name = {} # prime the dictionary: insert keys for the service pretty names, set the values to an empty list for s in Service.objects.all(): tickers_by_service_pretty_name[s.pretty_name] = [] # populate the values for ticker in Ticker.objects.all(): if not ticker.services_for_ticker: continue # convert the string of services into a list, one element per service name services_associated_with_ticker = ticker.services_for_ticker.split(",") # strip whitespace from each element in the list services_associated_with_ticker = [s.strip() for s in services_associated_with_ticker] for service_associated_with_ticker in services_associated_with_ticker: tickers_by_service_pretty_name[service_associated_with_ticker].append(ticker) # by this point, we've iterated over all tickers and via our dictionary know # all that are associated to any service # we'll now compile text summaries, one per service text_summaries = [] service_pretty_names = tickers_by_service_pretty_name.keys() service_pretty_names.sort() for service_pretty_name in service_pretty_names: print 'processing tickers for service ', service_pretty_name tickers_for_this_service = tickers_by_service_pretty_name[service_pretty_name] ticker_count_for_this_service = len(tickers_for_this_service) print 'how many tickers?', ticker_count_for_this_service if ticker_count_for_this_service == 0: continue tickers_for_this_service = sorted(tickers_for_this_service, key=lambda x: x.daily_percent_change, reverse=True) top_gainers = tickers_for_this_service[:3] top_losers = tickers_for_this_service[-3:] top_losers.reverse() # so that this smaller list is ordered from worst performance to less bad performance tickers_with_positive_movement = [t for t in tickers_for_this_service if t.daily_percent_change > 0.0] count_tickers_with_positive_movement = len(tickers_with_positive_movement) # we've identified the data points (top gainers, top losers, count of the tickers with positive movement); # now let's create the text description. # https://docs.python.org/2/library/string.html#format-specification-mini-language # https://docs.python.org/2/library/string.html desc_of_top_gainers = ['%s (%g%%)' % (t.ticker_symbol, t.daily_percent_change) for t in top_gainers] desc_of_top_gainers = ', '.join(desc_of_top_gainers) desc_of_top_losers = ['%s (%g%%)' % (t.ticker_symbol, t.daily_percent_change) for t in top_losers] desc_of_top_losers = ', '.join(desc_of_top_losers) percentage_positive_movement = '{:.2%}'.format(1.0*count_tickers_with_positive_movement/ticker_count_for_this_service) desc_of_positive_movement = "recs with gains today: %s (%d of %d)" % (percentage_positive_movement, count_tickers_with_positive_movement, ticker_count_for_this_service) summary_for_this_service = "%s %s" % (service_pretty_name, desc_of_positive_movement) summary_for_this_service += "\n %s" % desc_of_top_gainers summary_for_this_service += "\n %s" % desc_of_top_losers text_summaries.append(summary_for_this_service) print summary_for_this_service service_blurbs = '```' + "\n------------------------\n".join(text_summaries) + '```' headline = "*Ticker performance snapshot for %s *" % datetime.now().strftime('%a, %b %d, %Y %H:%M') # eg: Tue, May 12, 2015 11:15 subtitle = "(per service: top 3, worst 3, and % of recs with positive movement)" message_to_post = '\n'.join([headline, subtitle, service_blurbs]) post_message_to_slack(message_to_post)