Coders Packet

Bot for Stock Price updates in Python

By SHUBHAM GARG

This Bot provides all information about stocks of desired company in Discord channels messages using Python library yfinance.

Hello Learners!

This project aims to develop an interesting Stocks Price Bot that gives us data about loads of different organizations as messages in chosen discord channels.

Pre-requisite Skills

Python

Post Project Skills

Pandas
Plot.ly

Usage :

1.Install Python3
2.Install pip
3.Install all the prerequisites using : pip install -r prerequisites.txt
4.Extract the CSV files containing the stock details of a company: run stock.py
5.Use plot.ly to plot it.
6.Set up a Discord bot ans add basic commands like update.
7.Run bot.py:python bot.py [companycode]

Setting the Bot on Discord Platform:

Firstly, Import the yfinance, pandas, plotly and os module and download the CSV file containing stock details. Then, plot the closing price against the Datetime from the csv file using Plot.ly and export as a PNG file. The following code will help you out:

import pandas as pd
import csv
import yfinance as yf
import plotly.express as px
import plotly.graph_objects as go
import os

company=input("Company Code: ")
dataa = yf.download(company , period="1d" , interval="1m")
dataa.to_csv("Stock.csv")

#df = pd.read_csv('Stock.csv')
#df.head()
#fig = px.line(df, x = 'Datetime', y = 'Close', title='Tesla Stock Closing Prices against Time')

#cdf['Close'].plot(title="TSLA's stock price")

df = pd.read_csv('Stock.csv')
#ticker = yf.Ticker(company)

#cdf = ticker.history(period="max")
#cdf['Close'].plot(title="Stock price")

#trace = go.Scatter(x = cdf['Datetime'], y = cdf['Close'], name='Stock Prices of all years (in USD)')
trace1 = go.Scatter(x = df['Datetime'], y = df['Open'], name='Opening Prices (in USD)')
trace2 = go.Scatter(x = df['Datetime'], y = df['High'], name='High Prices (in USD)')
trace3 = go.Scatter(x = df['Datetime'], y = df['Low'], name='Low Prices (in USD)')
trace4 = go.Scatter(x = df['Datetime'], y = df['Close'], name='Closing Prices (in USD)')
trace5 = go.Scatter(x = df['Datetime'], y = df['Adj Close'], name='Adjusted Closing Prices (in USD)')
fig2 = go.Figure(data=[trace1, trace2, trace3, trace4,trace5] )
fig = go.Figure(trace4 )
#fig3 = go.Figure(trace )
fig.update_layout(title='Closing Prices against Time',
                   plot_bgcolor='rgb(230, 230,230)',
                   showlegend=True)
fig2.update_layout(title='Stock Prices against Time',
                   plot_bgcolor='rgb(230, 230,230)',
                   showlegend=True)
#fig3.update_layout(title='Stock Prices of all years against Time',
#                   plot_bgcolor='rgb(230, 230,230)',
#                   showlegend=True)

if not os.path.exists("images"):
    os.mkdir("images")
#plotly.io.orca.config.executable = '/content/images'
fig.write_image("images/fig1.png" , engine="kaleido")
fig2.write_image("images/fig2.png" , engine="kaleido")
#fig3.write_image("images/fig3.png" , engine="kaleido")

Sending updates in Discord :

The primary thing that our bot needs is an approach to give us day by day decisive updates of the stock data of an organization. To accomplish this, we need to set up an instrument which gives every day End-Of-Day stock updates, w.r.t. an organization's exchanging information, as instant messages. After fetching the CSV file, send the required data  as a message to a Discord Server channel. The code is illustrated below:

import os
import random
from discord.ext import commands
from dotenv import load_dotenv

import discord
from dotenv import load_dotenv
import stock

load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
os.system('python stock.py')
bot = commands.Bot(command_prefix='!')


client = discord.Client()

@client.event
async def on_ready():
    print(f'{client.user.name} has connected to Discord!')
    #print(f'Company Code of the desired Company')

@client.event
async def on_member_join(member):
    await member.create_dm()
    await member.dm_channel.send(
        f'Hi {member.name}, welcome to my Discord server!'
    )


@client.event
async def on_message(message):
    if message.author == client.user:
        return

    quotes = [
        'Hello, Hope you bought Pizza!',
        'Hello, Glad you are here!',
    ]
    if "$code " in message.content:
       quote = message.content
       codeparts = quote.split()
       code = codeparts[1]
       stock.company = code
       os.system('python stock.py')
    elif "hi " in message.content.lower():
        response = random.choice(quotes)
        await message.channel.send(response)
    elif message.content == 'raise-exception':
        raise discord.DiscordException
    elif message.content =='update':
        await message.channel.send(file=discord.File('C:/Users/hp/Desktop/Project/Stock.csv'))
        await message.channel.send(file=discord.File('C:/Users/hp/Desktop/Project/images/fig1.png'))
        await message.channel.send(file=discord.File('C:/Users/hp/Desktop/Project/images/fig2.png'))
        #await message.channel.send(file=discord.File('C:/Users/hp/Desktop/Project/images/fig3.png'))
        #await message.channel.send("Hi!")
    elif "Stockupdatesbot.logout()" == message.content.lower():
        await client.close()

@bot.command(name='create-channel')
@commands.has_role('admin')
async def create_channel(ctx, channel_name='real-python'):
    guild = ctx.guild
    existing_channel = discord.utils.get(guild.channels, name=channel_name)
    if not existing_channel:
        print(f'Creating a new channel: {channel_name}')
        await guild.create_text_channel(channel_name)



@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.errors.CheckFailure):
        await ctx.send('You do not have the correct role for this command.')


client.run(TOKEN)
bot.run(TOKEN)

Note: Create a .env file and add the discord token in that file.

Now Your DiscordServer Start running for Stock Updates! :)

Download Complete Code

Comments

No comments yet