How to use Raspberry PI for Stock Market Monitoring and Analysis with Python

5
(5)

Last Updated on 1st September 2023 by peppe8o

This tutorial will show you how to use a Raspberry PI for Stock Market monitoring and analysis with a few Python code lines and for free. It will show you how to get professional tools into your Raspberry PI computer board, without the need for expensive services.

This Tutorial Focus

This tutorial will not cover strategies and how to earn money with the Stock Market exchanges, as this isn’t the goal of the article, because it is really risky (and you must know the risks before starting), and because the web is plenty of people and websites that do this by job. But you will get all the tools for monitoring and automating your trading signals, so this can be useful also for professional traders wishing to add monitoring tools at a very cheap cost only for the Raspberry PI computer board (whose price starts from 20 USD).

Before starting, please note that financial stocks are identified by a symbol representing both the stock and the exchange market where it is traded. For example, Intesa San Paolo is an Italian bank traded in the Milan Exchange with the symbol “ISP.MI”, where the part after the dot identifies the exchange. I will assume here that you will select your stocks with this symbol notation (you can check the symbol for any Company as we’ll see in the following chapter).

What’s Different from Other Python Tutorials

Every stock market analysis starts with getting the Quotes for your stock.

Many other tutorials on the web explain how to get quotes with specific packages developed by the open-source community. But they sometimes reside in the people starting that specific development, sometimes breaking after the time with the new Python updates. Then, they pass the values to Pandas Dataframes.

This tutorial will use only Pandas Dataframes, so getting quotes directly into your dataframe object. Combined with 2 very simple custom functions, you will be able to get any stock historical quote with a single Python line.

The Quotes Source

The most common source in the world is Yahoo!Finance, which enables you to get worldwide stock quotations (even historical). And it is free.

Please mind that the use of Yahoo data is subject to their terms and conditions (available from their page) and this blog isn’t in any way connected with Yahoo.

Browsing their website, you can search for a specific symbol (or company name). This will return a page with the company summary. From here, please select the historical data (as shown in the following picture) and the new page will give you a list of the daily quotes and, the most important thing for us, a “Download” button:

yahoo-finance-isp-history

If you click it, you will download a CSV file of the quote history to your PC. But, if you right-click this link and copy the link address, you will find something similar to the following:

https://query1.finance.yahoo.com/v7/finance/download/ISP.MI?period1=1661436715&period2=1692972715&interval=1d&events=history&includeAdjustedClose=true

As you can see, the CSV URL is pretty simple: it combines a standard path with some queries. We’ll use this soon in our Python script.

What We Need

As usual, I suggest adding from now to your favourite e-commerce shopping cart all the needed hardware, so that at the end you will be able to evaluate overall costs and decide if to continue with the project or remove them from the shopping cart. So, hardware will be only:

raspberry-pi-zero-2-w-board-500px

It is important to note that if you want to keep the monitoring and analysis with text-line tools, you can opt for a cheap Raspberry PI Zero 2 W computer board. If you need to show charts with technical analysis indicators, you will need a Raspberry PI computer board with higher computing capabilities like a Raspberry PI 3 Model B or a newer one.

Step-by-Step Procedure

Prepare the Operating System

Please start installing the Raspberry PI OS. Here, we have 2 options (with the links for installation instructions):

  1. Raspberry PI OS Lite: This is a lightweight OS for Raspberry PI computer boards, without a Desktop environment (headless). You can opt for this OS if you DON’T need to show charts and you only need to implement scripts for stock monitoring and/or signals management
  2. Raspberry PI OS Desktop: This is a less-performing OS (compared to the lite version), but it runs really well on Raspberry PI computer boards. I suggest using this OS only if you need the charts showing price trends and Technical Analysis lines.

You can check the difference between the 2 operating systems with my Raspberry PI OS Lite vs Desktop: comparison between the 2 distributions article.

After installing the OS, please make it up-to-date. From the terminal:

sudo apt update -y && sudo apt upgrade -y

Install the required Packages

We need some packages in order to get my script working. The packages require pip, so the following 2 commands will do the job. Please note that the “mplfinance” library is not required if you don’t need the charts

sudo apt install python3-pip
pip3 install pandas mplfinance pandas_ta

Near the end of the installation process, you may get the following warnings:

WARNING: The scripts f2py, f2py3 and f2py3.9 are installed in '/home/pi/.local/bin' which is not on PATH.
 Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

WARNING: The scripts fonttools, pyftmerge, pyftsubset and ttx are installed in '/home/pi/.local/bin' which is not on PATH.
 Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

You can fix this warning by opening for editing your bashrc file:

nano ~/.bashrc

And append the following line at the end of this file:

export PATH="$HOME/.local/bin:$PATH"

Save and exit. You can reload the bashrc with the following terminal command without the need to logout or reboot:

source ~/.bashrc

Get my Stock Market Scripts

You can get my stock market scripts directly in your Raspberry PI with the wget terminal command.

Please use the following command to download the script WITHOUT charts:

wget https://peppe8o.com/download/python/stock-market/p8o-finance-no-chart.py

On the other hand, if you need to generate the charts, use the following wget command:

wget https://peppe8o.com/download/python/stock-market/p8o-finance-with-chart.py

Both the scripts are really similar. I will explain line by line the one with the chart generation, notifying you about the difference with the first script.

Explaining the p8o-finance-with-chart.py Script

This script starts by importing the required libraries. Here’s the first difference between the two scripts: it uses mplfinance only to generate the charts, so the import of this library is not required if you don’t need to generate them:

import pandas as pd
import mplfinance as mpf
import pandas_ta as ta
import os

After this first step, we’ll set a few variables.

  • stock: it is the symbol of the company we want to monitor, including the exchange symbol (for my example, “ISP.MI” means Intesa San Paolo, from the Milan exchange market). Change it with the symbol you want to monitor
  • interval: This is the date interval for each row. Usually, you don’t need to change it
  • history_years: This is the number of years of history we want to download for our stock
stock='ISP.MI'
interval='1d'
history_years=4

The first custom function has a simple job. The convert_dates() function converts the dates to UNIX timestamp type, as the Yahoo Finance query requires this type of date. the UNIX timestamp is a number counting the seconds between the 1st Jan 1970 and the required date.

The function, after importing soma date-related modules, calculates the UNIX dates for the history range according to the input, “history_yrs”. The end_date represents always today (at midnight, to be precise), while the start_date is calculated by subtracting the required number of years from the current date:

def convert_dates(history_yrs):
    from datetime import date, datetime
    import time
    from dateutil.relativedelta import relativedelta
    
    end_date = date.today() # midnight for YOUR timezone
    end_UNIX=round(time.mktime(end_date.timetuple()))

    start_date = end_date - relativedelta(years=history_yrs)
    start_UNIX=round(time.mktime(start_date.timetuple()))
    return start_UNIX, end_UNIX

The second (and last) custom function takes care of getting stock quotes. The get_stock_quotes() function, taking as input the stock symbol, checks if the stock data are already stored in the local Raspberry PI storage, with the “if os.path.exists(filename)” statement, and if the stored data are still actual compared to the current date, with the “and os.path.getmtime(filename) > today” statement within the same IF check.

If valid quotes are found, it uses the stored data in order to reduce the number of requests to the Yahoo Finance database. Otherwise, it downloads the full data and saves it locally, overwriting the existing file (if exists and is old).

It is important to note that if you need a backup of these data you should copy daily the generated CSV file into a different folder. At the same time, if you need to force the generation of a new CSV file, you can just remove the existing one.

In both cases, the function returns a pandas dataframe object with the quotes.

def get_stock_quotes(stock_name, hist_y):
    from datetime import date, datetime
    import time
    today=time.mktime(date.today().timetuple())
    filename=stock_name+'.csv'
    if os.path.exists(filename) and os.path.getmtime(filename) > today:
        print('Valid quotes file detected')
        df = pd.read_csv(filename)
        return df
    else:
        print('Creating new quotes file')
        (start_date, end_date)=convert_dates(hist_y)
        df = pd.read_csv('https://query1.finance.yahoo.com/v7/finance/download/'+stock_name+\
                         '?period1='+str(start_date)+\
                         '&period2='+str(end_date)+\
                         '&interval='+interval+\
                         '&events=history')
        df.to_csv(filename, index=False)
        return df

With these custom functions set, we can go back to our main program flow.

Getting a company’s historical quotes and assigning it to a variable, now, is as simple as issuing the following code line:

df=get_stock_quotes(stock, history_years)

Before showing you the results, please let me show a few code lines that will add also technical indicators.

For this tutorial, I will add 2 Simple Moving Average (SMA) with 2 time ranges: 20 and 80 days. The pandas_ta library helps in this task.

Before generating the two moving averages curves, we need to convert the “Date” column of our quotes, currently in a string format, to a datetime variable. The following line makes just this:

df['Date'] = pd.to_datetime(df['Date'])

Now, the calculation of the 2 SMA lines for the whole quote will be performed with the following code lines:

df.ta.sma(length=20, append=True)
df.ta.sma(length=80, append=True)

The “append=True” option edits the original dataframe appending the indicator as a new column.

Many other Technical Indicators are available from the pandas_ta library. The complete list is available from pandas-ta GitHub indicators page. Please note that each indicator requires specific inputs and you can check the required inputs as described in pandas-ta GitHub Main Page.

At this point, those using my script without chart generation can print the df dataframe and use it for analysis and signals, so getting a dataset similar to the following (it’s not part of the script code):

>>> %Run p8o-finance-no-chart.py
Valid quotes file detected
           Date    Open    High  ...     Volume    SMA_20    SMA_80
0    2019-08-26  1.9012  1.9524  ...  118697120       NaN       NaN
1    2019-08-27  1.9540  1.9668  ...  107341856       NaN       NaN
2    2019-08-28  1.9500  1.9762  ...  165815557       NaN       NaN
3    2019-08-29  1.9780  2.0325  ...  175020992       NaN       NaN
4    2019-08-30  2.0190  2.0275  ...  139750829       NaN       NaN
...         ...     ...     ...  ...        ...       ...       ...
1016 2023-08-21  2.4140  2.4600  ...   76490159  2.499900  2.399138
1017 2023-08-22  2.4570  2.4715  ...   63902901  2.496075  2.400075
1018 2023-08-23  2.4665  2.4810  ...   56396384  2.491875  2.401656
1019 2023-08-24  2.4725  2.4795  ...   64455239  2.487325  2.402644
1020 2023-08-25  2.4400  2.4705  ...   48457136  2.481150  2.403944

[1021 rows x 9 columns]

The following part of the script regards only the chart generation on Desktop devices, by mplfinance.

Mplfinance needs an indexed Date column. For this reason, the set_index method will do the transformation on the related column:

df.set_index(pd.DatetimeIndex(df["Date"]), inplace=True)

From this dataset, we create a new “data” dataframe with the main (common) columns to track prices on the chart and we’ll explicit the index column:

data=df[["Date","Open","High","Low","Close","Volume"]]
data.index = pd.DatetimeIndex(data['Date'])

We’ll also show in the chart the 2 SMA curves already calculated within the df dataframe. In order to do this, we’ll need to know what label these points get from the pandas_ta generation code. You can get the name by printing the dataframe (“print(df)” command to put after the indicator generation).

We’ll set these column names as variables for easier code understanding:

sma_20_name='SMA_20'
sma_80_name='SMA_80'

The following lines will add the two SMA lines to our plot object. Please note that you can add the option “panel=n”, where n is an integer starting from 1, to print the plot into a different panel (it’s easiest to try in your script in order to understand the result). This script keeps the 2 SMA lines inside the same panel of the prices, in order to overlap the prices. We’ll also set a specific color for each line:

sma_20_plot = mpf.make_addplot(df[sma_20_name],color='yellow')
sma_80_plot = mpf.make_addplot(df[sma_80_name],color='red')

The easiest way to insert additional plots into mplfinance is by creating a list object, which can include one or more plot objects in a list format:

plots = [sma_20_plot,sma_80_plot]

Finally, we generate the chart. It will be generated with a candle chart type, with colors style similar to those of Yahoo services, and the plots previously created.

Please note the “warn_too_much_data” option: this will avoid the default mplfinance warning message appearing on your shell when running a chart with a lot of point records. I’ve set it to 260*5, meaning (approximatively) 260 labour days per year multiplied for 5, resulting in 5 years.

mpf.plot(data,type='candle',volume=True,style='yahoo', addplot=plots, warn_too_much_data=260*5, title=stock)

The final result will show a chart like the following:

raspberry-pi-stock-market-chart-result

You can also zoom in the chart with the classic menu from matplotlib, which is the base of mplfinance:

raspberry-pi-stock-market-chart-result-zoom

Automating Raspberry PI Stock Market Signals

Now, you have your Stock quotes and Technical Indicators in your Raspberry PI. Besides showing the chart, the question is: how this can help me?

The answer is that Raspberry PI computer boards are very low power consumption devices, so you can keep them powered on all days without risking high energy bills. Moreover, you can configure them to run specific tasks to run at specified frequency.

Using a Cron Job you can download the stock data and compare the price value every day, then send email warnings to your email address at your signals trigger.

The process of email sending with a standard Python script and a Cron job is explained in my Send Email from Raspberry PI with Python tutorial. Keep the tutorial and mix it with the p8o-finance-no-chart.py script in order to reach your goal.

Next Steps

Interested in more projects with your RPI? Try to look at my Raspberry PI computer tutorial pages.

Enjoy!

How useful was this post?

Click on a star to rate it anonymously!

Average rating 5 / 5. Vote count: 5

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?