1
0
mirror of https://gitlab.com/simple-stock-bots/simple-discord-stock-bot.git synced 2025-06-16 07:16:41 +00:00

cleaning up code and figuring out discord.py

This commit is contained in:
Anson 2019-04-05 17:59:03 -07:00
parent 1e86d7a084
commit 941828c1d3
3 changed files with 132 additions and 91 deletions

View File

@ -1,4 +0,0 @@
secrets = {
'TOKEN': "https://discordapp.com/developers/applications/ > BOTNAME > Bot > 'copy token'",
'BRAVOS_API': 'https://bravos.co/a/data'
}

View File

@ -1,107 +1,47 @@
# Work with Python 3.6
import json
from discord.ext import commands
import discord
import re
import urllib.request
import credentials
import json
import tickerInfo as ti
# Make sure to update credentials.py with your secrets
TOKEN = credentials.secrets['TOKEN']
BRAVOS_API = credentials.secrets['BRAVOS_API']
BOT_PREFIX = ("?", "!")
TOKEN = "Discord Token"
TICKER_REGEX = "[$]([a-zA-Z]{1,4})"
client = commands.Bot(command_prefix=BOT_PREFIX)
@client.event # Make bot say when its ready
async def on_ready():
print('Bot is Ready!!!')
client = discord.Client()
@client.event
async def on_message(message):
"""
This runs every time a message is detected.
"""
if message.author == client.user: # Prevent bot from reacting to its own messages
# Check that message wasnt the bot.
if message.author == client.user:
return
# define information about the message
author = message.author
content = message.content.lower()
channel = message.channel
tickers = re.findall(TICKER_REGEX, message.content)
if tickers is not []:
print(tickers)
await client.send_typing(message.channel)
await client.send_message(message.channel, ti.tickerMessage(tickers))
return
try:
# regex to find tickers in messages, looks for up to 4 word characters following a dollar sign and captures the 4 word characters
tickers = re.findall('[$](\w{1,4})', content)
# print(message.author.id)
# get ticker information from bravos api, turns tickers into comma separated list so that only one api call is needed per message
url = 'https://data.bravos.co/v1/quote?symbols=' + ",".join(tickers) + \
'&apikey=' + BRAVOS_API + '&format=json'
# load json data from url as an object
with urllib.request.urlopen(url) as url:
data = json.loads(url.read().decode())
for ticker in tickers: # iterate through the tickers and print relevant info one message at a time
try: # checks if data is a valid ticker, if it is not tells the user
# Get Stock ticker name from Data Object
nameTicker = data[ticker.upper()]['name']
# Get Stock Ticker price from Object
priceTicker = data[ticker.upper()]['price']
# Checks if !news is called, and prints news embed if it is
if content.startswith('!news'):
embed = displayembed(ticker, nameTicker, priceTicker)
await client.send_message(channel, embed=embed)
else: # If news embed isnt called, print normal stock price
await client.send_message(channel, 'The current stock price of ' + nameTicker + ' is $**' + str(priceTicker) + '**')
except KeyError: # If searching for the ticker in loaded data fails, then Bravos didnt provide it, so tell the user.
await client.send_message(channel, ticker.upper() + ' does not exist.')
pass
except:
pass
# if message.content.startswith("!hello"):
# print(dir(message.author))
# msg = "Hello {0.author.mention}".format(message)
# await client.send_message(message.channel, msg)
# Prints an embed full of news about listed stock
def displayembed(ticker, nameTicker, priceTicker):
@client.event
async def on_ready():
print("Logged in as")
print(client.user.name)
print(client.user.id)
print("------")
embed = discord.Embed(
title='News for ' + nameTicker,
description='The current stock price of ' +
nameTicker + ' is $**' + str(priceTicker) + '**',
color=0x50bdfe
)
'''
Get ticker logo from Motley Fool, then get then print the following sources:
Bravos, Seeking Alpha, MSN Money, Yahoo Finance, Wall Street Journal, The Street.
'''
embed.set_thumbnail(
url='https://g.foolcdn.com/art/companylogos/mark/' + ticker + '.png')
embed.add_field(name='Bravos',
value='https://bravos.co/' + ticker, inline=False)
embed.add_field(name='Seeking Alpha',
value='https://seekingalpha.com/symbol/' + ticker, inline=False)
embed.add_field(
name='MSN Money', value='https://www.msn.com/en-us/money/stockdetails?symbol=' + ticker, inline=False)
embed.add_field(name='Yahoo Finance',
value='https://finance.yahoo.com/quote/' + ticker, inline=False)
embed.add_field(name='Wall Street Journal',
value='https://quotes.wsj.com/' + ticker, inline=False)
embed.add_field(
name='The Street', value='https://www.thestreet.com/quote/' + ticker + '.html', inline=False)
embed.add_field(
name='Zacks', value='https://www.zacks.com/stock/quote/' + ticker, inline=False)
return embed
async def list_servers():
await client.wait_until_ready()
while not client.is_closed:
print("Current servers:")
for server in client.servers:
print(server.name)
client.run(TOKEN)

105
tickerInfo.py Normal file
View File

@ -0,0 +1,105 @@
import urllib.request
import json
from datetime import datetime
import time
def tickerQuote(tickers):
"""Gathers information from IEX api on stock"""
stockData = {}
IEXURL = (
"https://api.iextrading.com/1.0/stock/market/batch?symbols="
+ ",".join(tickers)
+ "&types=quote"
)
print("Gathering Quote from " + IEXURL)
with urllib.request.urlopen(IEXURL) as url:
IEXData = json.loads(url.read().decode())
for ticker in tickers:
ticker = ticker.upper()
# Makes sure ticker exists before populating a dictionary
if ticker in IEXData:
stockData[ticker] = 1
stockData[ticker + "Name"] = IEXData[ticker]["quote"]["companyName"]
stockData[ticker + "Price"] = IEXData[ticker]["quote"]["latestPrice"]
stockData[ticker + "Change"] = round(
(IEXData[ticker]["quote"]["changePercent"] * 100), 2
)
stockData[ticker + "Image"] = stockLogo(ticker)
print(ticker + " Quote Gathered")
else:
stockData[ticker] = 0
return stockData
def stockNews(ticker):
"""Makes a bunch of strings that are links to news websites for an input ticker"""
print("Gather News on " + ticker)
newsLink = f"https://api.iextrading.com/1.0/stock/{ticker}/news/last/5"
print(newsLink)
with urllib.request.urlopen(newsLink) as url:
data = json.loads(url.read().decode())
news = {"link": [], "title": []}
for i in range(len(data)):
news["link"].append(data[i]["url"])
news["title"].append(data[i]["headline"])
return news
def stockLogo(ticker):
"""returns a png of an input ticker"""
logoURL = f"https://g.foolcdn.com/art/companylogos/mark/{ticker}.png"
return logoURL
def stockInfo(ticker):
infoURL = f"https://api.iextrading.com/1.0/stock/{ticker}/stats"
with urllib.request.urlopen(infoURL) as url:
data = json.loads(url.read().decode())
info = {}
info["companyName"] = data["companyName"]
info["marketCap"] = data["marketcap"]
info["yearHigh"] = data["week52high"]
info["yearLow"] = data["week52low"]
info["divRate"] = data["dividendRate"]
info["divYield"] = data["dividendYield"]
info["divDate"] = data["exDividendDate"]
return info
def stockDividend(ticker):
data = stockInfo(ticker)
print(data["divDate"])
if data["divDate"] == 0:
return "{} has no dividend.".format(data["companyName"])
line1 = "{} current dividend yield is: {:.3f}%, or ${:.3f} per share.".format(
data["companyName"], data["divRate"], data["divYield"]
)
divDate = data["divDate"]
# Pattern IEX uses for dividend date.
pattern = "%Y-%m-%d %H:%M:%S.%f"
# Convert divDate to seconds, and subtract it from current time.
divSeconds = datetime.strptime(divDate, pattern).timestamp()
difference = divSeconds - int(time.time())
# Calculate (d)ays, (h)ours, (m)inutes, and (s)econds
d, h = divmod(difference, 86400)
h, m = divmod(h, 3600)
m, s = divmod(m, 60)
countdownMessage = f"\n\nThe dividend is in: {d:.0f} Days {h:.0f} Hours {m:.0f} Minutes {s:.0f} Seconds."
message = line1 + countdownMessage
return message