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.
- Basic knowledge of python.
- 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
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.
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
close_price to see their values.
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
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
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
closing_prices hold all the opening and closing prices during the entire period. Let’s print to see the output ourselves.
[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
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)
.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.
['01 Apr 2020', '03 Apr 2020', ... '30 Mar 2021', '31 Mar 2021']
STEP 9: Zipping the values of
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.
[('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.
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
totsum = 0 for values in diff: totsum = totsum + values average = totsum/int(len(diff))
average holds the average increase or decrease the stock exhibited during the entire period.
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.