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)
Beispiel #3
0
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)