Building a Telegram Bot that delivers weekly stock open and close prices
Published: 2024-06-24 10:36:46

With Telegram, you can create a bot that helps you with different tasks such as giving you sports updates, coordinating how you receive membership payments in private groups, welcoming users to a group and removing spammers, etc. In this tutorial, you will learn how to create a telegram bot that retrieves the opening and closing prices of different stocks with python.

# Introduction

##  What are telegram bots?

Telegram bots are programmes that act as chat agents while performing sets of predefined instructions based on user inputs. There are various kinds of bots, each having different levels of complexity. For example, do you know that you can start a zoom meeting on telegram through their bot?

![Zoombot!](https://i.imgur.com/2tDMBrb.png "Zoombot")


# **Setting up your bot.**


## **Searching for BotFather on telegram**

You need to contact BotFather on telegram to create your unique bot. BotFather can be described as the command center that manages other bots. All you have to do is open your telegram app and look up BotFather from the search bar.

![Botfather!](https://i.imgur.com/gIBZoBv.png"Botfather")



## **Creating your Telegram Bot**

**Click on the /newbot option to create a new bot.**

![Newbot!](https://i.imgur.com/sgm1E8Z.png"Newbot")


## **Supplying your Bot’s name and username.**

You will be provided an option to insert your bot’s name, thereafter, its username.

**![Username!](https://i.imgur.com/KA42tcI.png")**


## **Getting your API keys**

When you are done, Telegram will supply you with API keys.

**![APIkeys!](https://i.imgur.com/8pra3Lr.png"APIKEYS")**

## **Installing Telegram Bot and Yahoo Finance python SDK**
You need to install the python Telegram-bot wrapper. The wrapper is a library that provides an asynchronous interface for the Telegram Bot API. You will also need to install yfinance, which offers a threaded and Pythonic way to download market data from [YahooFinance]([https://finance.yahoo.com/](https://finance.yahoo.com/).) 


**Open up your code editor and in your terminal and type:**

    $ pip install python-telegram-bot --upgrade

    $ pip install yfinance --upgrade --no-cache-dir



## **Writing scripts to receive messages sent to the bot.**

Here, you are going to import functions that would help us interpret the message sent to the bot. There’s also a slight modification in how the bot would work. When the user clicks on a start command, the bot would send a response containing the user’s name. The bot would expect a final input from the user, before completing the operation. This operation is represented in the image below.


**![Workflow!](https://i.imgur.com/KtOOMil.png"Workflow")**



```python
from  telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters

from telegram import Update

import logging

import yfinance as yf

from telegram import ForceReply, Update

  

#Defining bot Token & username

TOKEN = 'Insert your telegram Token'

BOT_USERNAME= '@Stock_Instruments_Bot'

  

logging.basicConfig(

format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',

level=logging.INFO

)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:

user = update.effective_user

await update.message.reply_html(

rf"Hi {user.mention_html()}! I am your Stock bot. Input your stock name/ticker (check Yahoo Finance for ideas), and I will give you the opening and closing prices for the past 5 days.",

reply_markup=ForceReply(selective=True),

)
```

  

## **Testing the bot connection.**

You will create a command handler that you have already registered with the bot and test. Each time you create a new async function or command, you would add it under the most recent command. The  `application.run_polling() `code shows if the bot is working at the terminal.


```python
if __name__ == '__main__':

application = ApplicationBuilder().token(TOKEN).build()

start_handler = CommandHandler('start', start)

application.run_polling()

```

## **Retrieving opening and closing prices**

The code below is written to retrieve the opening and closing for the past five days of any instrument the user inputs.

```python

async def instrumentprice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:

instrument_data_frombot = update.message.text

ticker_data = yf.Ticker(instrument_data_frombot)

instrument_data = ticker_data.info

try:

long_business_summary = instrument_data['longBusinessSummary']

except KeyError:

# If the instrument is not found, send an error message

await update.message.reply_text("Financial Instrument not found. Please check Yahoo Finance for the correct ticker code.")

# Construct the message with the business summary

message = f'*About*\n{long_business_summary}\n\n'

try:

hist =ticker_data.history(period="5d")

Open_Price = hist['Open']

Close_Price = hist['Close']

message += "\n*Here are the opening and closing prices for the past 5 days:\n"

for date in hist.index:

message += f"Date: {date.date()}\nOpen: {Open_Price[date]}\nClose: {Close_Price[date]}\n\n"

await update.message.reply_text(message)

except KeyError:
#If the instrument is not found, send an error message

await update.message.reply_text("Financial Instrument not found. Please check Yahoo Finance for the correct ticker code.")

```


##**Understanding the code:**

You have two objectives with this function. Retrieving the business summary and the open and closing prices. You retrieve the object that contains the business summary with the instrument_data variable. You use the try/ except method in both instances of retrieving the business summary and instrument prices because there’s a chance the operation can fail so you must account for the condition for when it does. When each of the exception handling methods are completed, the results are added to the message variable, and the bot outputs the response to the user.

## **Handling unknown input.**


When a user sends a message that the Bot is not equipped to handle, you create a function to take care of that.

 ```python

async def unknown(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:

await context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that command.")

```
## Full Code

```python
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters
import logging
import yfinance as yf
from telegram import ForceReply

# Defining bot Token & username
TOKEN = 'Insert Token'
BOT_USERNAME = '@Stock_Instruments_Bot'

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user = update.effective_user
    await update.message.reply_html(
        rf"Hi {user.mention_html()}! I am your Stock bot. Input your stock name/ticker (check Yahoo Finance for ideas), and I will give you the opening and closing prices for the past 5 days.",
        reply_markup=ForceReply(selective=True),
    )  

async def instrumentprice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    instrument_data_frombot = update.message.text
    ticker_data = yf.Ticker(instrument_data_frombot)
    instrument_data = ticker_data.info
    try:
        long_business_summary = instrument_data['longBusinessSummary']
    except KeyError:
        # If the instrument is not found, send an error message
        await update.message.reply_text("Financial Instrument not found. Please check Yahoo Finance for the correct ticker code.")
        return

    # Construct the message with the business summary
    message = f'*About*\n{long_business_summary}\n\n'
    try:
        hist = ticker_data.history(period="5d")
        Open_Price = hist['Open']
        Close_Price = hist['Close']
        message += "\n*Here are the opening and closing prices for the past 5 days:\n"
        for date in hist.index:
            message += f"Date: {date.date()}\nOpen: {Open_Price[date]}\nClose: {Close_Price[date]}\n\n"
        await update.message.reply_text(message)
    except KeyError:
        # If the instrument is not found, send an error message
        await update.message.reply_text("Financial Instrument not found. Please check Yahoo Finance for the correct ticker code.")

async def unknown(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that command.")

if __name__ == '__main__':
    application = ApplicationBuilder().token(TOKEN).build()
    
    start_handler = CommandHandler('start', start)
    instrumentprice_handler = MessageHandler(filters.TEXT & ~filters.COMMAND, instrumentprice)
    unknown_handler = MessageHandler(filters.COMMAND, unknown)
    
    application.add_handler(start_handler)
    application.add_handler(instrumentprice_handler)
    application.add_handler(unknown_handler)
    
    application.run_polling()
```




## **Conclusion.**

By installing the telegram and yahoo finance SDK, you built a bot that could retrieve the opening and closing prices for the previous five days. `


You saw how to create an account with BotFather and use the token generated to build a functional bot that could take instructions from users.The source code of the bot can be found on [Github](https://github.com/Pluri45/Finance-Telegram-Bot) and if you have further questions, you can drop them in the comments.