====== Monitoring stock price ====== I wrote a [[#Download|check script]] which will read quote for a specific stock from HKEX and monitor the bid price fluctuation. If the bid price goes beyond the upper or lower threshold, alert can be send. ===== Syntax ===== check_stock_quote.pl -s -w -c For example, to monitor the price of China Mobile, of stock code 00941: ./check_stock_quote.pl -s 00941 -w 70,80-c 65,85 OK: Current price 76.000 |'Price'=76.000;70.000,80.000;65.000,85.000 ===== Configuration ===== To use this script, define a check command and use it in a service: define command{ command_name check_stock_quote command_line $USER1$/check_stock_quote.pl -s $ARG1$ -w $ARG2$ -c $ARG3$ } define service{ ... service_description China Mobile 941 check_command check_stock_quote!00941!70,80!65,85 ... } ===== Use with PNP4Nagios ===== After enable performance processing, edit the auto created xml file at:''/var/log/nagios/rrd/perfdata/example-host/China_Mobile_941.xml''. Change the TEMPLATE to the custom template: **check_stock_quote**: Create template file ''/usr/share/nagios/pnp/templates/check_stock_quote.php'': # # Copyright (c) 2006-2008 Joerg Linge (http://www.pnp4nagios.org) # Plugin: check_nt -v MEMUSE # $Id: check_nt_mem.php 367 2008-01-23 18:10:31Z pitchfork $ # # Modified to check stock quote # $_my_upper_limit = $ACT[1] * 1.05; $_my_lower_limit = $ACT[1] * 0.95; $opt[1] = "-u $_my_upper_limit -l $_my_lower_limit --vertical-label \"Price\" --title \"$servicedesc\" "; # set graph background color $opt[1] .= "--color CANVAS#00004F "; $def[1] = "DEF:var1=$rrdfile:$DS[1]:MAX "; $def[1] .= "LINE1:var1#00FF00:\"Price\" " ; $def[1] .= "GPRINT:var1:LAST:\"%6.2lf Last \" " ; $def[1] .= "GPRINT:var1:AVERAGE:\"%6.2lf Average \" " ; $def[1] .= "GPRINT:var1:MAX:\"%6.2lf Max \\n\" "; ?> **Output sample**: {{:nagios:pnp-stock1.png}} ===== Download ===== #!/usr/bin/perl -w # Written by Michael Fung # Last update: 2010-02-09 use strict; use LWP::Simple; use Getopt::Long; use HTML::TableExtract; # url to fetch the quote: my $url = "http://www.hkex.com.hk/eng/invest/company/quote_page_e.asp?Month=1&langcode=e&WidCoID="; # return codes for nagios: my $OK = 0; my $WARN = 1; my $CRIT = 2; my $UNKNOWN = 3; # declare other vars: my $w_low; my $w_high; my $c_low; my $c_high; my $output = ''; my ( $stock_code, $o_warn, $o_crit, $help ); sub syntax { my $s; if ($s = shift) { printf STDERR ("Error: $s\n") unless ($help); } printf STDERR ("Syntax: check_stock_quote.pl -s -w -c \n"); exit(0) if $help; exit($UNKNOWN); } sub end { my $s = shift; my $i = shift; if ($i == $OK) { $s = "OK: $s"; } elsif ($i == $WARNING) { $s = "WARNING: $s"; } elsif ($i == $CRITICAL) { $s = "CRITICAL: $s"; } else { $s = "UNKNOWN: $s"; } print "$s\n"; exit($i); } Getopt::Long::Configure('bundling'); GetOptions( "s=s" => \$stock_code, "stock-code=s" => \$stock_code, "w=s" => \$o_warn, "c=s" => \$o_crit, "h" => \$help, "help" => \$help ) || syntax(); # --- syntax checks: syntax if ($help); syntax("Missing required parameters.") unless ($stock_code && $o_warn && $o_crit); ($w_low, $w_high) = split(',', $o_warn); ($c_low, $c_high) = split(',', $o_crit); syntax("Missing required parameters.") unless ($w_low && $w_high && $c_low && $c_high); # high values must not be smaller than low values if (($c_high < $c_low) || ($w_high < $w_low)) { syntax("High values must not be smaller than low values."); } # --- fetch the page: my $html = get($url . $stock_code) or end("Couldn't fetch the page.",$UNKNOWN); # find the price my $te = HTML::TableExtract->new( headers => ["Nominal Price"] ); $te->parse($html); # find the table with the "Nominal Price" column my $tb = $te->first_table_found() or end("Couldn't find the price column.",$UNKNOWN); my $price = $tb->cell(0,0) or end("Couldn't extract price data.",$UNKNOWN); # --- return results: # "Current price $price |'Price'=$price;$w_low,$w_high;$c_low,$c_high" $output = sprintf("Current price %.3f |'Price'=%.3f;%.3f,%.3f;%.3f,%.3f", $price,$price,$w_low,$w_high,$c_low,$c_high); if (($price > $c_high) || ($price < $c_low)) { end($output, $CRIT); } elsif (($price > $w_high) || ($price < $w_low)) { end($output, $WARN); } else { end($output, $OK); }