Introduction

This is a tutorial on making a simple program that will grab historical data from India’s National Stock Exchange for a given stock. We will filter the opening and closing prices and find how much our stock gained or lost each trading day. We will also export our results to an MS Excel file. We will be following a step-by-step format in this tutorial. One can find the complete program at the end of the article.

Prerequisite

  • Basic knowledge of python.

Objectives

  • Find out how much a stock gained or lost in each trading day for the given period.
  • Export the date, opening price, closing price, and the gain/loss to a CSV file.
  • Find out how much money was gained or lost on an average trading day.

PS: Complete code is available at the end

This is a very simple program. The first thing one needs to do is to install the NSEpy library which is used to extract historical and real-time data.

STEP 1: Open command prompt and run:

pip install nsepy

STEP 2: Import all the required libraries or methods

from nsepy import get_history
from datetime import *
import csv

The csv library will be useful later down the tutorial to export our data to a .csv file.

STEP 3: Fetching historical data of a specified stock in a given period. Here we are conducting the operation on Infosys (INFY)

data = get_history(symbol='INFY', start=date(2020, 4, 1), end=date(2021, 3, 31))

We are taking the data from the previous financial year (April 1, 2020 - March 31, 2021). Change the ticker and the date as per convenience. If we print the data right now, we will get the following output.

print(data)
  Symbol Series  Prev Close  ...  Trades  Deliverable Volume  %Deliverble


Date ...
2020-04-01 INFY EQ 641.50 ... 379235 6575764 0.5026
2020-04-03 INFY EQ 602.80 ... 261228 4711571 0.4609
2020-04-07 INFY EQ 585.70 ... 260480 8846122 0.5840
2020-04-08 INFY EQ 639.00 ... 235881 5570288 0.4718
2020-04-09 INFY EQ 631.60 ... 232901 6022789 0.5048
... ... ... ... ... ... ... ...
2021-03-24 INFY EQ 1371.55 ... 143327 3197000 0.5212
2021-03-25 INFY EQ 1353.75 ... 184200 5246781 0.5996
2021-03-26 INFY EQ 1333.80 ... 138471 2501215 0.5082
2021-03-30 INFY EQ 1336.20 ... 227944 5618355 0.5327
2021-03-31 INFY EQ 1385.30 ... 218153 4107507 0.4996

[249 rows x 14 columns]

The output is truncated for visual purposes. We can see there are 249 rows. This means there was a total of 249 trading days in the whole financial year. Here we have a host of information but we only want the opening price, closing price, and the date. The date is already used as the index, hence we can just fetch the opening price and closing price and it will be automatically indexed by the date.

STEP 4: Fetching opening and closing price.

open_price = data['Open']
close_price = data['Close']

Let’s try printing open_price and close_price to see their values.

print(open_price)
Date
2020-04-01 634.35
2020-04-03 603.50
2020-04-07 615.00
2020-04-08 630.00
2020-04-09 646.80
...
2021-03-24 1357.85
2021-03-25 1346.75
2021-03-26 1344.70
2021-03-30 1346.90
2021-03-31 1382.00
Name: Open, Length: 249, dtype: float64
print(close_price)
Date
2020-04-01 602.80
2020-04-03 585.70
2020-04-07 639.00
2020-04-08 631.60
2020-04-09 636.25
...
2021-03-24 1353.75
2021-03-25 1333.80
2021-03-26 1336.20
2021-03-30 1385.30
2021-03-31 1368.05
Name: Close, Length: 249, dtype: float64

As we can see, the opening price and the closing price has been matched with the date. Now, all we have to do is to subtract the opening price from the closing price to find gain/loss. For that, we will have to separately grab opening and closing prices from open_price and close_price.

STEP 5: Creating two lists to store values of opening and closing prices.

opening_prices = list()
closing_prices = list()

STEP 6: Passing all opening and closing prices to the above two lists.

for i in range(len(open_price)):
    openv = open_price._get_value(i, 'Open')
    opening_prices.append(openv)

for j in range(len(close_price)):
    closev = close_price._get_value(j, 'Close')
    closing_prices.append(closev)

Now the lists opening_prices and closing_prices hold all the opening and closing prices during the entire period. Let’s print to see the output ourselves.

print(opening_prices)
print(closing_prices)
[634.35, 603.5, ... 1346.9, 1382.0]
[602.8, 585.7, ... 1385.3, 1368.05]

STEP 7: Creating a list and storing the difference using for loop.

diff = list()

for k in range(len(open_price)):
    diff.append(closing_prices[k]-opening_prices[k])

Here we are using the open_price list for range but feel free to use close_price or opening_prices/closing_prices list to achieve the same. All these lists have the same number of items that we have to loop through. In this case, it is 249 which is the number of trading days as we have already seen above. Write now, we can print all three lists to get the output we want.

print(opening_prices)
print(closing_prices)
print(diff)
[634.35, ... 1346.9, 1382.0]
[602.8, ... 1385.3, 1368.05]
[-31.550000000000068, ... 38.399999999999864, -13.950000000000045]

As we can see, the three lists store opening price, closing price, and gain/loss respectively.

STEP 8: Taking the index (date) from the data and storing it in a list.

index_values = data.index

dates = list()

for row in index_values:
    row = row.strftime("%d %b %Y")
    dates.append(row)

We use .index method to grab the index values and store them in variable index_values. We then create a list called dates. We use a for loop to add the dates to the list. In the index_values, the type of the values is actually datetime.date object. We convert that to string using .strftime method. Let’s see the output at this point.

print(dates)
['01 Apr 2020', '03 Apr 2020', ... '30 Mar 2021', '31 Mar 2021']

STEP 9: Zipping the values of dates, opening_prices, closing_prices & diff lists.

stockdata = zip(dates, opening_prices, closing_prices, diff)
stockdata = list(stockdata)

Now the list stockdata contains a list of dates, opening prices, closing prices, and gain/loss. We can check the output at this point.

print(stockdata)
[('01 Apr 2020', 634.35, 602.8, -31.550000000000068), ... ('31 Mar 2021', 1382.0, 1368.05, -13.950000000000045)]\]

STEP 10: Exporting the data in to a CSV file.

with open('stockdata.csv', 'w', ) as file:
    wr = csv.writer(file)
    for item in stockdata:
        wr.writerow(item)

A file named stockdata.csv will be created in the root directory.

Screenshot of stockdata.csv

Warning: While the above file shows us how much our stock gained or lost during each trading day, they’re not reminiscent of our total gain or loss. We cannot sum the entire items in the diff list to find our gain/loss. That’s because of trading in off-market hours which is not accounted for here. The closing price of today need not be the opening price of tomorrow.

PS: When we rerun the program, the file will be overwritten.

STEP 11: Finding out average gain/loss during each trading day.

Okay, this is pretty much a bonus. If we want to know how much our stock gained or lost on an average trading day, there are few ways to find it out. Here we just add the items in the diff and divide them by the length of the diff list.

totsum = 0
for values in diff:
    totsum = totsum + values

average = totsum/int(len(diff))

The variable average holds the average increase or decrease the stock exhibited during the entire period.

print(average)
0.6965863453815213

Hence Infosys (INFY) gained an average of 0.69 INR per trading day in the previous financial year.

Warning again: We would like to repeat the above warning. This gain/loss is during trading hours. Off-market sales make a big difference. For that, we just have to subtract the opening price of day 1 from the closing price of the last day. Then one can divide it by the entire period.

Here is the complete program.

from nsepy import get_history
from datetime import *
import csv

data = get_history(symbol='INFY', start=date(2020, 4, 1), end=date(2021, 3, 31))

# print(data)

open_price = data['Open']
close_price = data['Close']

# print(open_price)
# print(close_price)


opening_prices = list()
closing_prices = list()

for i in range(len(open_price)):
    openv = open_price._get_value(i, 'Open')
    opening_prices.append(openv)

for j in range(len(close_price)):
    closev = close_price._get_value(j, 'Close')
    closing_prices.append(closev)

# print(opening_prices)
# print(closing_prices)

diff = list()

for k in range(len(open_price)):
    diff.append(closing_prices[k]-opening_prices[k])

# print(opening_prices)
# print(closing_prices)
# print(diff)

index_values = data.index

dates = list()

for row in index_values:
    row = row.strftime("%d %b %Y")
    dates.append(row)

# print(dates)

stockdata = zip(dates, opening_prices, closing_prices, diff)
stockdata = list(stockdata)

# print(stockdata)

with open('stockdata.csv', 'w', ) as file:
    wr = csv.writer(file)
    for item in stockdata:
        wr.writerow(item)

totsum = 0
for values in diff:
    totsum = totsum + values

average = totsum/int(len(diff))

# print(average)

Feel free to uncomment print(average) (or any other respectively) to print the average in to the console.

Written by Aravind Sanjeev, an India-based blogger and web developer. Read all his posts. You can also find him on twitter.