0: #!/usr/bin/perl
1:
2: =head1 NAME
3:
4: ticker - A stock monitoring client written for Peep: The Network
5: Auralizer.
6:
7: Peep takes virtual events and turns them into unobtrusive sounds like
8: birds chirping, rain falling, crickets doing whatever crickets do,
9: etc. It is frequently used for network and systems monitoring because it
10: is well suited for that task, but I recently added an API
11: to Net::Peep that allows customized clients to be built with very
12: little code.
13:
14: Since there are some stocks I follow I decided to make my first custom
15: client a stock ticker. Thanks to Finance::Quote, it took me about a
16: half-hour to write :-) A rooster crow or doorbell chime tells me that
17: something is happening with my stocks. And at the end of the day, it
18: e-mails me a report on any questionable activity.
19:
20: Though it is heavily commented, the code itself is quite short.
21:
22: =head1 USAGE
23:
24: ./ticker --help
25:
26: ./ticker --noautodiscovery --server=localhost --port=2001 --nodaemon
27:
28: If you have any problems, try turning on debugging output with
29: something like --debug=9.
30:
31: =head1 CONFIGURATION
32:
33: To use this client, include a section like the following in peep.conf:
34:
35: client ticker
36: class home
37: port 1999
38: config
39: # Stock symbol Stock exchange Event Max Min
40: RHAT nasdaq red-hat 4.0 3.6
41: SUNW nasdaq sun-microsystems 9.0 8.0
42: end config
43: notification
44: notification-hosts localhost
45: notification-recipients bogus.user@bogusdomain.com
46: notification-level warn
47: end notification
48: end client ticker
49:
50: and another section in the events block with something like
51:
52: events
53: #Event Type | Path to Sound File | # of sounds to load
54: ...
55: red-hat /usr/local/share/peep/sounds/misc/events/rooster.* 1
56: sun-microsystems /usr/local/share/peep/sounds/misc/events/doorbell.* 1
57: end events
58:
59: =head1 AUTHOR
60:
61: Collin Starkweather <collin.starkweather@colorado.edu> Copyright (C) 2001
62:
63: =head1 SEE ALSO
64:
65: perl(1), peepd(1), Net::Peep, Net::Peep::Client, Net::Peep::BC,
66: Net::Peep::Notifier, Net::Peep::Notification, Finance::Quote
67:
68: http://peep.sourceforge.net
69:
70: =cut
71:
72: # Always use strict :-)
73: use strict;
74: use Net::Peep::BC;
75: use Net::Peep::Log;
76: use Net::Peep::Client;
77: use Net::Peep::Notifier;
78: use Net::Peep::Notification;
79: use Finance::Quote;
80: use vars qw{ %config $logger $client $quoter $conf };
81:
82: # The Net::Peep::Log object will allow us to print out some things in
83: # a nicely formatted way so we can tell ourselves what we're doing ...
84: $logger = new Net::Peep::Log;
85:
86: # Instantiate a Peep client object. The client object handles most of
87: # the dirty work for us so we don't have to worry about things such as
88: # forking in daemon mode or parsing the command-line options or the
89: # Peep configuration file.
90: $client = new Net::Peep::Client;
91: $quoter = new Finance::Quote;
92:
93: # First we have to give the client a name
94: $client->name('ticker');
95:
96: # Now we initialize the client. If the initialization returns a false
97: # value, we display documentation for the script and exit.
98: $client->initialize() || $client->pods();
99:
100: # Now we assign a parser that will parse the 'ticker' section of the
101: # Peep configuration file
102: $client->parser( \&parse );
103:
104: # Now we tell the client to get the information from the configuration
105: # file. It returns a Net::Peep::Conf, the Peep configuration object,
106: # which contains information from the configuration file.
107: $conf = $client->configure();
108:
109: # Register a callback which will be executed every 60 seconds. The
110: # callback is simply a function which checks the price of the stock
111: # and peeps every time it exceeds the maximum or minimum price that
112: # has been set.
113: $client->callback( \&loop );
114:
115: # Start looping. The callback will be executed every 60 seconds ...
116: $client->MainLoop(60);
117:
118: sub parse {
119:
120: # Parse the config section for the ticker client in the Peep
121: # configuration file
122:
123: # We'll use a regular expression to extract the ticker information
124: # and stuff it into a data structure (the global variable %config)
125:
126: # This subroutine will be used to parse lines from peep.conf such
127: # as the following and store the information in %config:
128: # RHAT nasdaq red-hat 4.0 3.6
129: # SUNW nasdaq sun-microsystems 9.0 8.0
130: for my $line (@_) {
131: if ($line =~ /^\s*([A-Z]+)\s+(\w+)\s+([\w\-]+)\s+([\d\.]+)\s+([\d\.]+)/) {
132: my ($symbol,$exchange,$event,$max,$min) = ($1,$2,$3,$4,$5,$6);
133: $config{$symbol} = { event=>$event, exchange=>$exchange, max=>$max, min=>$min };
134: }
135: }
136:
137: } # end sub parse
138:
139: sub loop {
140:
141: for my $key (sort keys %config) {
142: $logger->log("Checking the price of [$key] ...");
143: # Fetch some information about the stock including the price
144: my %results = $quoter->fetch($config{$key}->{'exchange'},$key);
145: my $price = $results{$key,'price'};
146: $logger->log("\tThe price of [$key] is [$price].");
147: if ($price > $config{$key}->{'max'} or $price < $config{$key}->{'min'}) {
148: $logger->log("\tThe price is out of bounds! Sending notification ....");
149: # The price is out of bounds! We'll start peeping ...
150: my $broadcast = Net::Peep::BC->new('ticker',$conf);
151: $broadcast->send('ticker',
152: type=>0,
153: sound=>$config{$key}->{'event'},
154: location=>128,
155: priority=>0,
156: volume=>255);
157: # In case we're away from our desk, we'll also send out an
158: # e-mail notification. Don't want to miss the action!
159: my $notifier = new Net::Peep::Notifier;
160: my $notification = new Net::Peep::Notification;
161: $notification->client('ticker');
162: $notification->status('crit');
163: $notification->datetime(time());
164: $notification->message("The price of $key is $price!");
165: $notifier->notify($notification);
166: }
167: }
168:
169: } # end sub loop
170:
171: __END__
In reply to A new take on the old stock ticker by Starky
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |