def stock_history_response(request): time = request["time"] start = time["start"] end = time["end"] if end > datetime.datetime.now(): return nl.turnIntoResponse( "Please provide a range of dates in the past.") if start == end: start = end - datetime.timedelta(days=7) companies = request["companies"] for industry in request["areas"]: companies = union(companies, companiesInIndustry(industry)) chart = Chart() desc = "Here's how the stock price of " l = [] for company in companies: try: hist = Company.objects.get(ticker=company).getStockHistory( start, end) except ValueError: return nl.turnIntoResponse("Please enter a more recent date.") chart.add_from_sh(company, hist) l.append( Company.objects.get(ticker=company).name + " (" + company + ")") desc += nl.makeList(l) if (len(companies) > 1): desc += " have " else: desc += " has " desc += " changed between " + nl.printDate(start) + " and " + nl.printDate( end) + "." return nl.turnChartIntoChartResponse(chart.toJson(), desc)
def respond_to_request(request): """ Given a request object, find the relevant data and format it correctly. """ quality = request["quality"] if quality == "price": #Responses to price return stock_price_response(request) elif quality == "news": return news_response(request) elif quality == "priceDiff": return price_difference_response(request) elif quality == "percentDiff": return percent_difference_response(request) elif quality == "stockHist": return stock_history_response(request) elif quality == "volume": return volume_response(request) elif quality == "joke": if len(request["companies"]) == 0 and len(request["areas"]) == 0: return nl.turnIntoResponse("To get to the other side.") else: companies = request["companies"] for i in request["areas"]: companies = union(companies, companiesInIndustry(i)) return nl.turnIntoResponse("To buy stock in " + nl.makeList(companies) + ".") else: print(request) if 0 < len(request["areas"]) + len(request["companies"]): # get all the companies refered to in the query all_comps = [] for name in request["areas"]: comps = Industry.objects.get(name=name).companies.all() for c in comps: all_comps.append(c.ticker) for ticker in request["companies"]: all_comps.append(ticker) if request["comparative"] is not None: chart = Chart() now = datetime.datetime.now() dw = datetime.timedelta(days=7) for ticker in all_comps: c = Company.objects.get(ticker=ticker) chart.add_from_sh(ticker, c.getStockHistory(now - dw, now)) desc = higherLower(request["comparative"], all_comps, "percentage difference", getPercentDiff, lambda x: nl.printAsPercent(x)) return nl.turnChartIntoChartResponse(chart.toJson(), desc["body"]) else: request["quality"] = "price" return stock_price_response(request) return nl.turnIntoResponse("ERROR: Cannot respond about " + quality)
def stock_price_response(request): companies = request["companies"] areas = request["areas"] comparative = request["comparative"] time = request["time"] if "now" not in time: return stock_history_response(request) if comparative is not None: group = companies for i in areas: group = union(group, companiesInIndustry(i)) if len(group) == 0: group = allCompanies() return higherLower(comparative, group, "stock price", getSpotPrice, nl.printAsSterling) if len(companies) == 0: #Special text response for just one industry: if len(areas) == 1: message = "Here's the current price of the " + areas[ 0] + " industry:" caption = Industry.objects.get(name=areas[0]).getSpotPrice() caption = nl.printAsSterling(caption) return nl.turnIntoResponseWithCaption(message, caption) elif len(areas) == 0: return nl.turnIntoResponse( "You'll need to tell me the names of the companies you'd like the stock price of." ) elif len(companies) == 1 and len(areas) == 0: message = "Here's " + nl.posessive(companies[0]) + " current price:" caption = Company.objects.get(ticker=companies[0]).getSpotPrice() caption = nl.printAsSterling(caption) return nl.turnIntoResponseWithCaption(message, caption) #If no special conditions are met: return makeBarChartOf(companies, "Current Stock price", getSpotPrice, areas)
def higherLower(comparative, companies, qualName, funct, formatFunct): caption = "Out of " companySet = [] bestName = "???" bestPrice = -1 higher = (comparative == "higher" or comparative == "highest") for company in companies: c = Company.objects.get(ticker=company) price = funct(c) if (price > bestPrice and higher) or (price < bestPrice and (not higher)) or bestPrice == -1: bestPrice = price bestName = company companySet.append(c.name + " (" + company + ")") caption += nl.makeList(companySet) if len(companies) >= 100: caption = "Out of all companies" elif len(companies) >= 8: caption = "Out of those companies" caption += ", " + bestName + " has the " if higher: caption += "highest " else: caption += "lowest " caption += qualName + ", at " + formatFunct(bestPrice) + "." return nl.turnIntoResponse(caption)
def volume_response(request): companies = request["companies"] areas = request["areas"] comparative = request["comparative"] time = request["time"] if comparative is not None: group = companies for i in areas: group = union(group, companiesInIndustry(i)) if len(group) == 0: group = allCompanies() return higherLower(comparative, group, "volume", lambda x: x.getVolume(), lambda x: x) if len(companies) == 0: if len(areas) == 1: message = "Here's the most recent total trading volume of the " + areas[ 0] + " industry:" caption = Industry.objects.get(name=areas[0]).getVolume() return nl.turnIntoResponseWithCaption(message, caption) elif len(areas) == 0: #Response for no companies or industries being listed. return nl.turnIntoResponse( "You'll need to tell me the names of the industries you want the trading volume of." ) elif len(companies) == 1: message = "Here's " + nl.posessive( companies[0]) + " most recent trading volume:" caption = Company.objects.get(ticker=companies[0]).getVolume() return nl.turnIntoResponseWithCaption(message, caption) #If no special case is met return makeBarChartOf(companies, "Recent Trading Volume", lambda x: x.getVolume(), print_format=lambda x: str(x))
def price_difference_response(request): companies = request["companies"] areas = request["areas"] comparative = request["comparative"] time = request["time"] if "now" not in time: return stock_history_response(request) if comparative is not None: group = companies for i in areas: group = union(group, companiesInIndustry(i)) if len(group) == 0: group = allCompanies() return higherLower(comparative, group, "price difference", getPriceDiff, nl.printAsSterling) if len(companies) == 0: if len(areas) == 1: message = "Here's the most recent price difference of the " + areas[ 0] + " industry:" caption = getPriceDiff(Industry.objects.get(name=areas[0])) caption = nl.printAsSterling(caption) return nl.turnIntoResponseWithCaption(message, caption) elif len(areas) == 0: #Response for no companies or industries being listed. return nl.turnIntoResponse( "You'll need to tell me the names of the companies you'd like the price difference of." ) elif len(companies) == 1: message = "Here's " + nl.posessive( companies[0]) + " most recent price difference:" caption = getPriceDiff(Company.objects.get(ticker=companies)) caption = nl.printAsSterling(caption) return nl.turnIntoResponseWithCaption(message, caption) #If no special case is met return makeBarChartOf(companies, "Recent Price Difference", getPriceDiff)
def percent_difference_response(request): companies = request["companies"] areas = request["areas"] comparative = request["comparative"] if comparative is not None: group = companies for i in areas: group = union(group, companiesInIndustry(i)) if len(group) == 0: group = allCompanies() return higherLower(comparative, group, "percentage difference", getPercentDiff, nl.printAsPercent) if len(companies) == 0: if len(areas) == 1: message = "Here's the most recent percentage difference of the " + areas[ 0] + " industry:" caption = getPercentDiff(Industry.objects.get(name=areas[0])) caption = nl.printAsPercent(caption) return nl.turnIntoResponseWithCaption(message, caption) #Response for no companies being listed. return nl.turnIntoResponse( "You'll need to tell me the names of the companies you'd like the percentage difference of." ) elif len(companies) == 1: message = "Here's " + nl.posessive( companies[0]) + " most recent percentage difference:" caption = getPercentDiff(Company.objects.get(ticker=companies[0])) caption = nl.printAsPercent(caption) return nl.turnIntoResponseWithCaption(message, caption) else: return makeBarChartOf(companies, "Recent Percentage Difference", getPercentDiff, [], lambda x: "%.2f%%" % x)
def ask_chatbot(request): """ Given a query in the POST data, it will parse the message then return a valid response. """ query = request.POST.get("query") trader = request.user.traderprofile data = {"name": "FLORIN", "messages": []} requests = nl.getRequests(query) if requests == [] or requests == None: data["messages"].append(nl.genericUnknownResponse()) else: for request in requests: # for each company that was requested, incremenet the hit count for ticker in request["companies"]: try: hc = CompanyHitCount.objects.get(company__ticker=ticker, trader=trader) hc.hit_count += 1 hc.save() except ObjectDoesNotExist: CompanyHitCount.objects.create( company=Company.objects.get(ticker=ticker), trader=trader, hit_count=1) # for each industry that was requested, incremenet the hit count for name in request["areas"]: try: hc = IndustryHitCount.objects.get(industry__name=name, trader=trader) hc.hit_count += 1 hc.save() except ObjectDoesNotExist: IndustryHitCount.objects.create( industry=Industry.objects.get(name=name), trader=trader, hit_count=1) if request["quality"] == "joke": data["messages"].append( nl.turnIntoResponse("Why did the chicken cross the road?")) try: data["messages"].append(respond_to_request(request)) except Exception as e: data["messages"].append({ "name": "FLORIN", "type": "text", "body": "Sorry, something went wrong with your " + " query.", "caption": str(e) if len(str(e)) < 30 else '' }) print("--------------------- ERROR ---------------------") logging.exception("Error while parsing %s query" % request["quality"]) print("------------------ REQUEST OBJ ------------------") print(request) print("-------------------------------------------------") return JsonResponse(data)
def news_response(request): time = request["time"] companies = request["companies"] articles = [] sentimentScore = 0 analysed = 0 for industry in request["areas"]: companies = union(companies, companiesInIndustry(industry)) if len(companies) == 0: return nl.turnIntoResponse( "You'll need to specify which companies you'd like news about.") for company in companies: if "now" in time: news = Company.objects.get(ticker=company).getNews() else: news = Company.objects.get(ticker=company).getNewsFrom( time["start"], time["end"]) for story in news: score = sentiment.getSentiment(story.description)["compound"] articles.append(story.toJson()) sentimentScore += score analysed += 1 if len(articles) == 0: if "now" in time: return nl.turnIntoResponse( "I'm sorry, I couldn't find any news for " + \ nl.makeOrList(companies) + \ " for this week. You can specify earlier articles in your query if you wish." ) else: return nl.turnIntoResponse( "I'm sorry, I couldn't find any news for " + \ nl.makeOrList(companies) + \ " from " + nl.printDate(time["start"]) ) resp = nl.turnIntoNews(articles) if analysed > 0: sentimentScore = sentimentScore / analysed resp["heading"] = "Here's the news I found:" if sentimentScore > 0.2: resp["heading"] = "It seems the news is pretty positive." elif sentimentScore < -0.2: resp["heading"] = "It seems the news is pretty negative." return resp