- Added delete command

- added watchlists
- added $pf2 and $wl2 to get image format table outputs
- moving yahoo finance commands to separate file
This commit is contained in:
socks 2021-02-14 18:57:18 +00:00
parent f3a622b95f
commit 35fc806327
9 changed files with 265 additions and 60 deletions

View file

@ -1,35 +0,0 @@
import json
import asyncio
from config import config
db = config['database']
def write_file(data):
with open(db, 'w') as f:
f.write(data)
def get_stocks(user):
with open(db) as f:
data = json.loads(f.read())
if user in data.keys():
user_data = data[user]
return user_data['portfolio']
else:
data[user] = {"portfolio": {}}
write_file(json.dumps(data))
return get_stocks(user)
def add_stock(user, stock, amount):
with open(db) as f:
data = json.loads(f.read())
if user in data.keys():
print(data.keys())
if stock in data[user]['portfolio'].keys():
data[user]['portfolio'][stock] += amount
else:
data[user]['portfolio'][stock] = amount
write_file(json.dumps(data))
return True
else:
get_stocks(user)
return add_stock(user, stock, amount)

View file

@ -1 +0,0 @@
socks@meme-machine.555521:1612898779

View file

@ -21,13 +21,11 @@ def get_stocks(user):
data = json.loads(f.read())
data = dict(data)
print("USER" + str(user))
if user in list(data.keys()):
user_data = data[user]
return user_data['portfolio']
else:
print(data)
data[user] = {"portfolio": {}}
data[user] = {"portfolio": {}, "watchlist": {}}
write_file(json.dumps(data))
return get_stocks(user)
@ -35,8 +33,6 @@ def add_stock(user, stock, amount):
with open(db) as f:
data = dict(json.loads(f.read()))
print(data)
print(type(data))
if user in data.keys():
if stock in data[user]['portfolio'].keys():
data[user]['portfolio'][stock] = str(Decimal(amount) + Decimal( data[user]['portfolio'][stock] ))
@ -48,3 +44,63 @@ def add_stock(user, stock, amount):
else:
get_stocks(user)
return add_stock(user, stock, amount)
def delete_stock(user, stock):
with open(db) as f:
data = json.loads(f.read())
if user in data.keys():
# user exists
portfolio = data[user]['portfolio']
if stock in portfolio.keys():
# stock exists
del portfolio[stock]
data[user]['portfolio'] = portfolio
write_file(json.dumps(data))
return get_stocks(user)
def get_watchlist(user):
with open(db) as f:
data = json.loads(f.read())
if user not in data.keys():
get_stocks(user)
get_watchlist(user)
return data[user]['watchlist']
def watch(user, stock, est_price=0):
with open(db) as f:
data = json.loads(f.read())
if user not in data.keys():
get_stocks(user)
add_to_watchlist(user, list_name, stock)
if not stock_exists(stock):
return False
watchlist = data[user]['watchlist']
watchlist[stock] = str(Decimal(est_price))
data[user]['watchlist'] = watchlist
write_file(json.dumps(data))
return True
def unwatch(user, stock):
with open(db) as f:
data = json.loads(f.read())
if user not in data.keys():
get_stocks(user)
return
if not stock_exists: return
watchlist = data[user]['watchlist']
del watchlist[stock]
data[user]['watchlist'] = watchlist
write_file(json.dumps(data))

104
main.py
View file

@ -1,7 +1,10 @@
import discord
import database, table
import database, table, yfi
import table2 as t2
from discord.ext import commands
from config import config
from decimal import Decimal
import typing
intents = discord.Intents.default()
@ -16,22 +19,119 @@ async def ping(ctx):
await ctx.send("pong!")
@bot.command(aliases=['pf'])
async def portfolio(ctx):
user = str(ctx.message.author)
return await ctx.send(str( "```" + table.generate_table(database.get_stocks(user)) + "```" ))
@bot.command()
async def pf2(ctx):
user = str(ctx.message.author)
portfolio = database.get_stocks(user)
data = []
for stock in portfolio.keys():
data.append([
stock,
Decimal(portfolio[stock]),
round(float(Decimal(portfolio[stock]) * Decimal(yfi.get_current_price(stock))), 2)
])
data.append(["Total", "", round( sum([x[2] for x in data]), 2) ] )
image = t2.generate_table(
headers = ["Ticker", "Shares", "Value ($)"],
data = data,
title = str(user + "'s Portfolio")
)
await ctx.send(file=discord.File(image, 'table.png'))
image.close()
@bot.command()
async def add(ctx, stock, amount):
user = str(ctx.message.author)
stock = stock.upper()
try:
float(amount)
except ValueError:
await ctx.send("amoutn not a number")
return
user = str(ctx.message.author)
if database.add_stock(user, stock, amount):
return await ctx.send(str( "```" + table.generate_table(database.get_stocks(user)) + "```" ))
else:
return await ctx.send("Stock **{0}** does not exist!".format(stock))
@bot.command(aliases=['del'])
async def delete(ctx, stock):
stock = stock.upper()
user = str(ctx.message.author)
return await ctx.send(str( "```" + table.generate_table(database.delete_stock(user, stock)) + "```" ))
@bot.command(aliases=['wl'])
async def watchlist(ctx):
user = str(ctx.message.author)
wlist = database.get_watchlist(user)
return await ctx.send( str ( "```" + table.watchlist_table(wlist) + "```") )
@bot.command(aliases=['w'])
async def watch(ctx, stock, est_price: typing.Optional[int]):
if not est_price:
est_price = 0
user = str(ctx.message.author)
stock = stock.upper()
try:
float(est_price)
except ValueError:
await ctx.send("Estimated price not a number")
return
if database.watch(user, stock, est_price):
return await ctx.send("Updated watchlist")
else:
return await ctx.send("Stock **{0}** does not exist!".format(stock))
@bot.command(aliases=['uw'])
async def unwatch(ctx, stock):
user = str(ctx.message.author)
stock = stock.upper()
database.unwatch(user, stock)
return await ctx.send("Updated watchlist")
@bot.command()
async def wl2(ctx, user: typing.Optional[discord.Member]):
if not user:
user = str(ctx.message.author)
else:
print(str(user))
user = str(user)
watchlist = database.get_watchlist(user)
data = []
for stock in watchlist.keys():
data.append([
stock,
yfi.get_current_price(stock),
Decimal(watchlist[stock]),
])
image = t2.generate_table(
headers = ["Ticker", "Value ($)", "Est. Price ($)"],
data = data,
title = str(user + "'s Watchlist"),
bg = 'lightgreen', border='limegreen'
)
await ctx.send(file=discord.File(image, 'table.png'))
image.close()
bot.run(config['apikey'])

View file

@ -1 +1 @@
{"Katte#3575": {"portfolio": {"AAPL": "0.37795852", "GME": "6.43", "AMD": "0.2661378", "AMZN": "0.00534034", "ETH-USD": "0.02", "HMMJ.TO": "14.14"}}, "Haedrien#6134": {"portfolio": {"UAMY": "150", "GME": "92.922", "ZOM": "100", "otlk": "100", "zsan": "100", "CTRM": "13.48"}}, "Forchex#1473": {"portfolio": {"AMC": "12", "GME": "19.7", "TGB": "56.52"}}, "Stonks#4179": {"portfolio": {"TANH": "100", "MICT": "100", "CEPU": "100", "NEXT": "100", "FTK": "100", "AVCO": "100", "CJJD": "100"}}}
{"Katte#3575": {"portfolio": {"AAPL": "0.37795852", "GME": "6.43", "AMD": "0.2661378", "AMZN": "0.00534034", "ETH-USD": "0.02", "HMMJ.TO": "14.14", "BTC-USD": "0.00038396"}, "watchlist": {"AAPL": "150", "GME": "0", "AMD": "0", "AMZN": "0"}}, "Haedrien#6134": {"portfolio": {"UAMY": "150", "GME": "92.922", "ZOM": "100", "otlk": "100", "zsan": "100", "CTRM": "13.48"}, "watchlist": {}}, "Forchex#1473": {"portfolio": {"AMC": "12", "GME": "19.7", "TGB": "56.52"}, "watchlist": {}}, "Stonks#4179": {"portfolio": {"TANH": "100", "MICT": "100", "CEPU": "100", "NEXT": "100", "FTK": "100", "AVCO": "100", "CJJD": "100", "GLDG": "100", "ORLA": "100"}, "watchlist": {}}}

BIN
table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -1,26 +1,12 @@
from tabulate import tabulate
from decimal import Decimal
import yfinance as yf
def get_current_price(ticker):
yf_obj = yf.Ticker(ticker)
todays_data = yf_obj.history(period='1d')
return round(todays_data['Close'][0], 2)
stonks = {
'MSFT': 4.3,
'AAPL': 13,
'GME' : 212
}
import yfi as y
def generate_table(stonks):
table_data = []
total = 0
for ticker in stonks.keys():
price = get_current_price(ticker)
price = y.get_current_price(ticker)
shares_count = stonks[ticker]
table_data.append([ticker, shares_count, round(Decimal(price) * Decimal(stonks[ticker]), 2)])
total += (Decimal(price) * Decimal(stonks[ticker]))
@ -28,3 +14,18 @@ def generate_table(stonks):
table_data.append(['Total', '', round(total, 2)])
return str( tabulate(table_data, ['Ticker', 'Shares', 'Value ($)'], tablefmt="pretty") )
def watchlist_table(watchlist):
table_data = []
header = ['Ticker', 'Current Price ($)', 'Estimated Price ($)']
for stonk in watchlist.keys():
table_data.append([
stonk,
y.get_current_price(stonk),
watchlist[stonk],
])
return str( tabulate( table_data, header, tablefmt="pretty" ) )

76
table2.py Normal file
View file

@ -0,0 +1,76 @@
import matplotlib.pyplot as plt
import matplotlib, io
from datetime import datetime
def generate_table(headers, data, title="", bg='skyblue', border='steelblue'):
timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
font = {'family' : 'monospace',
'weight' : 'normal',
'size' : 12}
matplotlib.rc('font', **font)
title_text = title
footer_text = timestamp
fig_background_color = bg
fig_border = border
column_headers = headers
if data:
cell_text = []
for row in data:
cell_text.append([x for x in row])
else:
cell_text = [["No Data"] + ["" for x in range(len(headers)-1)]]
# Create the figure. Setting a small pad on tight_layout
# seems to better regulate white space. Sometimes experimenting
# with an explicit figsize here can produce better outcome.
image_height = (( 0.9375 + ( 0.40625 * ( len(data) + 1) ) ) * 160)
image_width = 6 * 160
plt.figure(linewidth=2,
edgecolor=fig_border,
facecolor=fig_background_color,
tight_layout={'pad':1},
dpi=160,
figsize=(image_width/160, image_height/160)
)
# Add a table at the bottom of the axes
the_table = plt.table(cellText=cell_text,
colLabels=column_headers,
loc='center')# Scaling is the only influence we have over top and bottom cell padding.
# Make the rows taller (i.e., make cell y scale larger).
the_table.scale(1, 2)
# Hide axes
ax = plt.gca()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# Hide axes border
plt.box(on=None)
# Add title
plt.suptitle(title_text)
# Add footer
plt.figtext(((image_width - 15)/image_width), 1-((image_height - 15)/image_height), footer_text, horizontalalignment='right', size=12, weight='light')
# Force the figure to update, so backends center objects correctly within the figure.
# Without plt.draw() here, the title will center on the axes and not the figure.
plt.draw()
# Create image. plt.savefig ignores figure edge and face colors, so map them.
image_buffer = io.BytesIO()
plt.savefig(image_buffer, format='png')
image_buffer.seek(0)
return image_buffer

8
yfi.py Normal file
View file

@ -0,0 +1,8 @@
import yfinance as yf
def get_current_price(ticker):
yf_obj = yf.Ticker(ticker)
todays_data = yf_obj.history(period='1d')
return round(todays_data['Close'][0], 2)