Projecting Market Indexes in QGIS with Python

We are now going to learn how to project data from market indexes in QGIS. Our intention is to obtain a real time world view of the current status of the largest indexes around the world. In order to achieve that, we are going to use the Python console in QGIS and download stock data with the python library YahooFinancials. We will then inject that data into the database of a shape file and project those numbers onto the map.

Getting the Shape File for Our Market Indexes in Qgis

The first thing that we are going to need is a shape file (.shp) representing the countries of the world. Such a file can be easily found with a simple Google search and is available on various websites, so we won’t go into detail about searching for that here. After adding the shapefile layer in QGIS, it should look similar to this:

We are going to add two identical world layers, as the idea here is to have one base layer outlining all countries and then use a layer on top of the first one to show a color scale between red and green depending on the current state of the chosen indexes. If we didn’t have an initial, in this case, gray base layer it would look odd when trying to project a color scale only for those countries for which we have obtained data.

Adding Tables With Market Indexes In QGIS

After opening the top layer’s attribute table, you should edit it in accordance with the following column structure:

  • OBJECTID is self-explanatory and is a unique number representing each polygon area (country) of the shape file.
  • REGION_WB denotes which region the country belongs to.
  • NAME_EN is the column with the names of each country.

So far so good, but now we are now going to move on to the columns which concern the actual stock data:

  • Ticker is the Yahoo Finance stock market ticker for the market in question. For the United States, the ticker would for example be ^GSPC (S&P500), for Sweden ^OMXS30 (OMXS30) and for Canada ^GSPTSE (S&P/TSX Composite index). A more comprehensive list is shown in the next image.
  • Marketname represents the name of the actual market.

Below, we see a table with the various tickers that I have used for this demo:

The Selection Of Market Indexes In QGIS Might Seem Arbitrary

A few things should be said about this selection. When making it, I considered what I believed to the be the largest and most common indexes. That being said, my selection based on these criteria can certainly be debated. I have also added the market names manually, and hence they are not the result of any name look-up function within python, although there is the possibility to do so.

Now, the last two columns would be:

  • Marketstat, which is going to contain the daily percentage change in relation to the closing value of the previous trading day, i.e., how much the markets are up or down today.
  • Label_name, which will contain the same value as Marketstat, but with an added “%” sign and converted to a string value. This is the column that we will use for the labels when creating a map in QGIS.

The next thing we are going to do is to set the correct label that is to be shown after the values have been injected into the database:

As can be seen from the above image, we have chosen Value: Label_name in order to, as mentioned, show the value representing the market status with an added “%” sign and the code for achieving that follows further down. Moving on to the layer’s symbology, we want the polygon area to show different colors depending on the market status. For example, if the markets have gone up today, the color will be some shade of green, and if it has gone down, it will be some shade of red.

Symbology and market indexes in QGIS.

We select a Graduated symbology and a color ramp that goes from red to green, with Equal Count (Quantile) as mode. The interval has been manually set to [-6, 6], but the value of 0 will not show up since that is not how markets work. The value/column chosen in this case will be Marketstat and not Label_name,as we want to deal with a numerical value for the color ramp and not a string. It should be said that the interval selection is somewhat arbitrary, as markets can go up or down more than that, but you can of course adjust the values as you see fit.

Running The Python Code In Order To Project Market Indexes In QGIS

Now, we will open the python console in QGIS and start working with the script. In order to get this script to work, we will only need to import one library, and that would be YahooFinancials:

from yahoofinancials import YahooFinancials

We Only Need to Write One Function to Display Market Indexes in QGIS

Subsequently, we then write our first function, which will be called get_market_percentage. That function will take the Yahoo Finance index ticker as input and return the percentage value of how much that particular index has gone up or down since the last trading day:

def get_market_percentage(ticker):

#Get last close value
previous_close = YahooFinancials(ticker).get_prev_close_price()
#Get current price/value
current_price = YahooFinancials(ticker).get_current_price()
market_status = (current_price / previous_close) - 1
#Convert to percentage
market_status_percent = round(market_status * 100, 2)
return(market_status_percent)

Calling The Functions Within The YahooFinancials Library

There are two main functions to be observed here. We use the supplied ticker in to call a function within the YahooFinancials library called get_prev_close_price, which then retrieves the closing price from the previous trading day. The second function is get_current_price, which returns the current value associated with the same supplied ticker. We then divide the current price with the last closing price and perform a few conversions of the number in order to get the percentage value.

After our first and only function has been written, it is time to move on to start editing the layer at hand.

#Load and start editing the currently selected layer
lyr = iface.activeLayer()
lyr.startEditing()
features = lyr.getFeatures()

The first thing to do is to load the selected layer containing the market indexes in QGIS. Since we are only working with one layer here, apart from the background one, I am going to use the function activeLayer. However, if we have several layers, it would make more sense to switch to another function when selecting which layer that is going to be edited. As always within QGIS, we need to start an editing session before we can insert values into the attribute table/database, which we do by calling the function startEditing. The final step is to get all the features from that particular layer by calling the getFeatures function.

Injecting The Market Indexes In QGIS Into The Attribute Table

Now that we are able to edit the attribute table of the layer, it is time to loop through the different rows among the loaded features. For each row in the attribute table we first need to clear the values in order not to have old values in the table. This is done by setting the Marketstat value for the current row in features to “”. It can be argued that this part is sort of unnecessary, but if we later change which countries we have added tickers for after one reading, we might get a map with mixed values after the second reading.

for feat in features:

attrs = feat.attributes()
#Clear all marketstat values before we proceed
feat['Marketstat'] = ""
#Start working with shape file areas where there is a ticker
if not attrs[3] == NULL:

#Call to funtion above to get market price
market_perc = get_market_percentage(str(attrs[3]))
#Update "Marketstat" field in database
feat['Marketstat'] = market_perc
#Fill a separate field in the database with value plus "%"

#for estethic purposes. To be loaded as labels.

labelname = str(market_perc) + "%"
feat['Label_name'] = labelname
#Command line output of loaded values
print("Loading", str(attrs[4]), labelname)

#Update the layer with the new attributes
lyr.updateFeature(feat)

The only rows in the attribute table that we want to deal with are the ones where there is a predefined ticker. Hence, if there is a NULL value in the table where a ticker should be, then we move on to the next row.

Something should be said in regards to the indexing here. In QGIS it can sometimes happen, if you delete and add columns, that the indexing of the columns don’t turn out to have the same value as you initially thought. Some basic testing may be necessary in order to determine which is which.

After having come across a row that has a ticker value, we call the aforementioned get_market_percentage function with that ticker. Then, we inject the retrieved value into the Marketstat value for that particular row. The market status for the given market has now been retrieved and stored, but due to the labeling purposes discussed above it will also be necessary to inject that same percentage together with a “%” sign in the Label_name field for the current row.

Updating And Committing The Changes In Order To Project Market Indexes In QGIS

When all of the rows with tickers have received their values, we call the updateFeature function of the layer in order to update the values. The final step is then to call the commitChanges function of the layer (outside of the loop) in order to commit those changes:

#Commit the changes
lyr.commitChanges()

At this point, it is time to run the script. When doing so it will probably take some time for all of the values to load, so be aware of this. Once the script has terminated, you should get a visualization representing the status of the given market indexes, similar to the example below:

Projection of market indexes in QGIS.

Each time you run the script, you will get a visualization of market indexes in QGIS, showing how the different market indexes around the world are currently doing. Happy scripting!

Johan Bengtsson