Skip to content

davidhintelmann/Datareader_TMX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

If you are looking for the original repo please checkout og branch.

Montreal Exchange (TMX)

The Montreal Exchange is the oldest exchange in Canada and has a very important history to Canada's economy. Taken from Wikipedia,

The Montreal Exchange, formerly the Montreal Stock Exchange (MSE), is a derivatives exchange, located in Montreal, Quebec, Canada that trades futures contracts and options on equities, indices, currencies, ETFs, energy and interest rates. Since 1965, it has been located in the Tour de la Bourse (Stock Exchange Tower), Montreal's third-tallest building. It is owned by the Toronto-based TMX Group.

This README file is to showcase the functionality of this small web scraping module. It can be used to get options prices, both calls and puts for index and ETF options, equity options, currency options, and weekly options.

These prices are then displayed in a Pandas Dataframe for further analysis. This could include simple plots for visualizing the data or creating machine learning model or neural network to predict future prices. One could also use Black-Scholes model to gain further insight.


Requirements

  1. Python 3.11.5
  2. Pandas 2.1.0 (older version will probably work)
  3. Requests 2.31.0 (older version will probably work)
  4. bs4 4.12.2 (for BeautifulSoup)
    • lxml 5.3.0 used with bs4 to process xml and html

We start by showing a list of options available from TMX. There is one parameter for the function get_list() and it can take one of four stings:

'Index'/'ETF', 'Equity', 'Currency', or 'Weekly'.

The webpage looks like: Options list from Montreal Exchance (TMX)

get_list('equity')
Name of underlying instrument Option symbol Underlying symbol
0 Aecon Group Inc. ARE ARE
1 AGF Management Ltd., Cl. B AGF AGF.B
2 Agnico Eagle Mines Limited AEM AEM
3 Air Canada AC AC
4 Alamos Gold Inc. AGI AGI
... ... ... ...
264 Wheaton Precious Metals Corp. WPM WPM
265 Whitecap Resources Inc. WCP WCP
266 Winpak Ltd. WPK WPK
267 WSP Global Inc. WSP WSP
268 Yamana Gold Inc. YRI YRI

269 rows × 3 columns

The above DataFrame that we get with get_list('equity') is from: Equity Options list from Montreal Exchance (TMX)

Now we can grab stock prices for Air Canada (ticker symbol AC) so we can compare them to the stock options:

get_stock('AC')
TICKER Last price Net change Bid price Ask price
0 AC 15.520 0.000 15.520 15.550

We can also input a list of stock symbols to get a Pandas DataFrame of said stocks:

get_stock(['AC','ARE'])
TICKER Last price Net change Bid price Ask price
0 AC 15.520 0.000 15.520 15.550
1 ARE 14.220 0.100 14.200 14.250

Finally, we obtain the a Pandas Dataframe of TMX stock options for Air Canada which comes from:

Equity Options list from Montreal Exchance (TMX)

get('AC')
Call Bid price Ask price Last price Impl. vol. Open int. Vol. Strike Put Bid price_ Ask price_ Last price.1 Impl. vol_ Open int_ Vol_
0 Oct 23, 2020-W 2.05 2.20 2.20 86.5% 10 0 13.5 Oct 23, 2020-W 0.01 0.12 0.12 75.8% 17 0
1 Oct 23, 2020-W 1.57 1.77 1.77 79.0% 0 0 14.0 Oct 23, 2020-W 0.08 0.14 0.14 71.0% 30 0
2 Oct 23, 2020-W 1.12 1.24 1.24 62.5% 10 0 14.5 Oct 23, 2020-W 0.10 0.18 0.18 59.2% 23 10
3 Oct 23, 2020-W 0.73 0.84 0.84 57.0% 7 0 15.0 Oct 23, 2020-W 0.19 0.29 0.29 53.8% 57 7
4 Oct 23, 2020-W 0.44 0.54 0.54 56.0% 47 141 15.5 Oct 23, 2020-W 0.37 0.53 0.53 53.7% 46 1
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
153 Jan 20, 2023 3.55 7.35 7.35 76.4% 2 0 21.0 Jan 20, 2023 8.85 12.50 12.50 74.4% 0 0
154 Jan 20, 2023 3.30 7.20 7.20 76.3% 0 0 22.0 Jan 20, 2023 9.60 13.30 13.30 74.2% 0 0
155 Jan 20, 2023 3.10 7.00 7.00 76.2% 0 0 23.0 Jan 20, 2023 10.35 14.10 14.10 73.8% 0 0
156 Jan 20, 2023 2.84 6.80 6.80 75.6% 0 0 24.0 Jan 20, 2023 11.10 14.85 14.85 73.0% 0 0
157 Jan 20, 2023 3.15 5.00 5.00 69.3% 32 7 25.0 Jan 20, 2023 11.90 15.75 15.75 73.3% 0 0

158 rows × 15 columns

import pandas as pd
import requests
from bs4 import BeautifulSoup
"""
Get a list of options from https://m-x.ca/nego_liste_en.php
TMX website

Index and ETF options
Equity options
Currency options
Weekly options
"""
def get_list(market=str) -> pd.DataFrame:
    tmx = "https://m-x.ca/nego_liste_en.php" # TMX website, where data is taken from
    
    #check that parameter is of type string
    is_str1 = isinstance(market, str)
    if not is_str1:
        raise TypeError("market parameter must be of type string")
        
    try:
        market = market.lower()
    except Exception as e:
        print(e)
    else:
        if market == 'index' or market == 'etf':
            market = 0
        elif market == 'equity':
            market = 1
        elif market == 'currency':
            market = 2
        elif market == 'weekly':
            market = 3
        else:
            raise Exception("Did not enter market type, choose from Index or ETF, Equity, Currency, Weekly.")
        df = pd.read_html(tmx)
        return df[market]
"""
Get options prices at predetermined dates from TMX website
Call/Puts
strike price
Bid/Ask spreads
open interest
implied volatility
volume
"""
def get(ticker_symbol=str) -> pd.DataFrame:
    tmx = "https://m-x.ca/nego_cotes_en.php" # TMX website, where data is taken from

    is_str1 = isinstance(ticker_symbol, str)
    if not is_str1:
        raise TypeError("ticker_symbol parameter must be of type string")
        
    try:
        ticker_symbol = ticker_symbol.upper()
    except Exception as e:
        print(e)
    else:
        url = tmx + '?symbol=' + ticker_symbol + '*'
        df = pd.read_html(url)
        df[0].rename(columns={'Bid price.1':'Bid price_', 'Ask price.1':'Ask price_', 'Last Price.1':'Last Price_',
                             'Impl. vol..1':'Impl. vol_', 'Open int..1':'Open int_', 'Vol..1':'Vol_'}, inplace=True)
        return df[0].iloc[:-1] #do not include last row, rubbish information
"""
Get stock price from TMX to compare to strike price
can accept string or list of strings
"""
def get_stock(ticker_symbol=str) -> pd.DataFrame:
    tmx = "https://m-x.ca/nego_cotes_en.php" # TMX website, where data is taken from
    
    #check that parameter is of type string
    is_str1 = checktype(ticker_symbol)
    if not is_str1:
        raise TypeError("market parameter must be of type string")

    #download stock price, remember it is 15 minutes delayed
    try:
        symbols = []
        for n in ticker_symbol: 
            symbols.append(n.upper())

    except Exception as e:
        print(e)
    else:
        price_dict = {}
        is_list = isinstance(ticker_symbol, list)
        if is_list:
            df_list = []
            for m in symbols:
                URL = tmx + '?symbol=' + m + '*'
                response = requests.get(URL)
                soup = BeautifulSoup(response.text, 'html.parser')
                x = soup.find('div', class_ = 'quote-info', attrs = 'ul')
                y = x.ul.text.split('\n')[1:-2]
                
                price_dict['TICKER'] = m
                for z in y:
                    key, value = z.split(':')
                    price_dict[key] = value
                tmp_df = pd.DataFrame.from_dict(price_dict, orient='index').T
                df_list.append(tmp_df)
            return pd.concat(df_list, ignore_index=True)
        else:
            ticker_symbol = ticker_symbol.upper()
            URL = tmx + '?symbol=' + ticker_symbol + '*'
            response = requests.get(URL)
            soup = BeautifulSoup(response.text, 'html.parser')
            x = soup.find('div', class_ = 'quote-info', attrs = 'ul')
            y = x.ul.text.split('\n')[1:-2]

            price_dict['TICKER'] = ticker_symbol
            for z in y:
                key, value = z.split(':')
                price_dict[key] = value
            tmp_df = pd.DataFrame.from_dict(price_dict, orient='index').T
            return tmp_df
            
def checktype(obj):
        return bool(obj) and all(isinstance(elem, str) for elem in obj)

About

Get Stock Option Prices from TMX (Montreal Exchange)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published