Last active
May 19, 2020 19:20
-
-
Save mark05e/8d25c3b96b9e44e1fca1284b0d8126cf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# IndiaNSE.pm | |
# | |
# Copyright (C) 1998, Dj Padzensky <[email protected]> | |
# Copyright (C) 1998, 1999 Linas Vepstas <[email protected]> | |
# Copyright (C) 2000, Yannick LE NY <[email protected]> | |
# Copyright (C) 2000, Paul Fenwick <[email protected]> | |
# Copyright (C) 2000, Brent Neal <[email protected]> | |
# Copyright (C) 2013, Manoj Kumar <https://lists.gnucash.org/pipermail/gnucash-user/2015-August/061672.html> | |
# Copyright (C) 2020, Mark <https://gist.github.com/mark05e>, | |
# Philip <https://www.pcnworld.com/> | |
# | |
# This program is free software; you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation; either version 2 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program; if not, write to the Free Software | |
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
# 02111-1307, USA | |
# | |
# This code derived from Padzensky's work on package Finance::YahooQuote, | |
# but extends its capabilites to encompas a greater number of data sources. | |
# | |
# This code is derived from Finance::Quote::IndiaMutual 1.18 | |
# | |
# This code was developed as part of GnuCash <http://www.gnucash.org/> | |
package Finance::Quote::india_nse; | |
require 5.30.2; | |
use strict; | |
use vars qw($VERSION); | |
use Finance::Quote::SymbolTranslation qw(symbol_translation); | |
use IO::Uncompress::Unzip qw(unzip $UnzipError); | |
# Updated downloader requirements | |
# use File::Basename; | |
use LWP::UserAgent; | |
use LWP::Simple qw($ua getstore); | |
use URI; | |
use HTTP::Status; | |
$VERSION = '1.20'; | |
my $URL = 'https://www1.nseindia.com'; | |
my $BHAV_ZIP = $ENV{TEMP} ? "$ENV{TEMP}/nse_bhav.zip" : '/tmp/nse_bhav.zip'; | |
my $BHAV_CSV = $ENV{TEMP} ? "$ENV{TEMP}/nse_bhav.csv" : '/tmp/nse_bhav.csv'; | |
sub methods { | |
return ( | |
india_shares => \&india_nse, | |
india_nse => \&india_nse | |
); | |
} | |
{ | |
my @labels = qw/currency date isodate method price success symbol/; | |
sub labels { | |
return ( | |
india_shares => \@labels, | |
india_nse => \@labels | |
); | |
} | |
} | |
sub get_bhav_url { | |
my $time = shift; | |
my @months = ('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'); | |
my ($mday, $month, $year, $filename); | |
(undef, undef, undef, $mday, $month, $year, undef, undef, undef) = localtime($time); | |
$month = $months[$month]; | |
$year += 1900; | |
$filename = "cm".$mday.$month.$year."bhav.csv.zip"; | |
# sample -- /content/historical/EQUITIES2013/NOV/cm22NOV2013bhav.csv.zip | |
return("/content/historical/EQUITIES/$year/$month/$filename"); | |
} | |
sub india_nse { | |
my $quoter = shift; | |
my @symbols = @_; | |
my $debug = 0; | |
if (@symbols && $symbols[0] eq 'Debug') { # if first symbol is Debug, enable debugging | |
$debug = 1; | |
shift @symbols; | |
} | |
return unless @symbols; | |
my (%info, $errormsg, $fh, $ref_trans_2); | |
my ($url, $reply); | |
$ua->default_headers( | |
HTTP::Headers->new( | |
'Accept' => '*/*', | |
'Connection' => 'keep-alive', | |
'Accept-Language' => 'en-US,en;q=0.9', | |
'User-Agent' => 'Why are you making it hard for us?' | |
) | |
); | |
for (my ($nb_days, $time) = (0, time); $nb_days < 7; $nb_days++, $time -= 24 * 60 * 60) { | |
$url = $URL . get_bhav_url($time); | |
if ($debug) { | |
print "DEBUG: URL = $url"; | |
} | |
# Download file | |
$reply = getstore( $url, $BHAV_ZIP ); | |
printf "\nResult: $reply, URL: $url"; | |
if ($debug) { | |
print "DEBUG: Reply = ", is_success($reply) ? "Successful" : "Unsuccessful", " : ", $reply, "\n"; | |
} | |
last if (is_success($reply) || $reply == 200); | |
} | |
unless (is_success($reply) or $reply == 200) { | |
$errormsg = "\nHTTP failure : " . $reply; | |
} | |
unless ($errormsg) { | |
if (! unzip $BHAV_ZIP => $BHAV_CSV) { | |
$errormsg = "\nUnzip failure : $UnzipError"; | |
} | |
} | |
unless ($errormsg) { | |
if (! open $fh, '<', $BHAV_CSV) { | |
$errormsg = "\nOpen failure : $!"; | |
} | |
} | |
unless ($errormsg) { | |
(undef, $ref_trans_2) = symbol_translation('india_nse', \@symbols, 1); | |
# SYMBOL,SERIES,OPEN,HIGH,LOW,CLOSE,LAST,PREVCLOSE,TOTTRDQTY,TOTTRDVAL,TIMESTAMP,TOTALTRADES,ISIN, | |
while (<$fh>) { | |
my @data = split /\s*,s*/; | |
next unless (@data > 10); | |
my $symbol = uc($data[0]); | |
next unless exists $ref_trans_2->{$symbol}; | |
$symbol = $ref_trans_2->{$symbol}; | |
$info{$symbol, 'symbol'} = $data[0]; | |
$info{$symbol, 'currency'} = 'INR'; | |
$info{$symbol, 'price'} = $data[5]; | |
$quoter->store_date(\%info, $symbol, {eurodate => $data[10]}); | |
$info{$symbol, 'success'} = 1; | |
} | |
close($fh); | |
} | |
unless ($errormsg) { | |
$errormsg = 'Stock lookup failed'; | |
} | |
foreach my $symbol (@symbols) { | |
$info{$symbol, 'method'} = 'india_nse'; | |
next if (exists $info{$symbol, 'success'}); | |
$info{$symbol, 'success'} = 0; | |
$info{$symbol, 'errormsg'} = $errormsg; | |
} | |
return wantarray ? %info : \%info; | |
} | |
1; | |
=head1 NAME | |
Finance::Quote::india_nse - Fetch quotes from NSE, India http://www.nseindia.com | |
=head1 SYNOPSIS | |
use Finance::Quote; | |
$q = Finance::Quote->new(); | |
%info = $q->fetch('india_shares', 'TCS'); # Failover to other methods ok. | |
%info = $q->fetch('india_nse', 'TCS'); # Use this module only. | |
=head1 DESCRIPTION | |
This module obtains information about shares listed on NSE, India from NSE, India web site http://www.nseindia.com. | |
The information is taken from the Bahv copy file (zipped CSV) prepared by NSE at the end of the trading day. | |
This file is mirrored in a local file. | |
This module uses Finance::Quote::SymbolTranslation for symbol translation. Source name for this purpose is india_nse. | |
=head1 SYMBOL TRANSLATION | |
If failover method india_shares is used with india_nse and india_icici_direct as | |
sources, the same symbol can not be used with both these providers. | |
In order to use the same symbol for both these sources, Finance::Quote::SymbolTranslation | |
can be used to translate common symbol name to one specific to each source. | |
For example, the symbol used for Infosys is INFY and INFTEC for NseIndia and | |
india_icici_direct respectively. | |
To be able to use symbol INFY with india_source method with NseIndia and | |
india_icici_direct as sources, create / modify fq_symbol_translation.txt and add | |
following line - | |
icici_direct INFY INFTEC | |
F::Q will ask both NseIndia and india_icici_direct to fetch information about INFY, but | |
india_icici_direct will translate INFY to INFTEC, fetch information about INFTEC and | |
return data as if it fetched data for INFY. | |
Similarly, to be able to use symbol INFTEC with india_source method with NseIndia and | |
india_icici_direct as sources, create / modify fq_symbol_translation.txt and add | |
following line - | |
india_nse INFTEC INFY | |
fq_symbol_translation.txt file should be either in the current directory or in | |
the home directory (on windows machines, in the directory given by USERPROFILE | |
environment varibale) | |
=head1 LABELS RETURNED | |
this source returns following lables on success: | |
currency - INR | |
date - date in US (mm/dd/yyyy) format | |
isodate - date in ISO (yyyy-mm-dd) format | |
method - india_nse | |
price - closing price in INR | |
symbol - NSE symbol | |
success - 0 = failure / 1 = success | |
errormsg - only if success is 0 | |
=head1 SEE ALSO | |
NSE, India web site http://www.nseindia.com. | |
Finance::Quote, | |
Finance::Quote::SymbolTranslation | |
=cut |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment