Hello all,
I wanted to share a project of mine. I wanted one of my router's LEDs (a generally unused one) to show movement in a stock in real-time. So, I wrote this script (below) that you could call as an /etc/init.d service, if you'd like (instructions below). It's sudo-code logic is as follows:
loop[
check day & time to see if stocks are trading (premarket + regular hours work fine, afterhours do not)
if time is not ok, wait 600 secs
if time is ok, pull stock data, set LED pattern, then wait 600 secs.
]
LED pattern is as follows:
- Mostly on blinking corresponds to stock being up, every 1s of LED on between blinks = 1% movement in stock.
Ex1. Stock up 3.28% would generate a 3.28s on, 50ms off, 3.28s on, 50ms off, repeating pattern. - Mostly off blinking corresponds to stock being down, every 1s of LED off between blinks = 1% movement in stock.
Ex2. Stock down 7.1% would generate a 7.1s off, 50ms on, 7.1s off, 50ms on, repeating pattern.
NOTE: The obervant of you will notice that the pattern would be the same if the stock were up 0.05% or down 0.05%, namely: 0.05s (50ms) on, 0.05s (50ms) off, repeating. I am ok w/ this ambiguity since up/down 0.05% is a fairly trivial move.
See demo video here. For reference my stock was up 1% at the time of recording.
Some configuration/prerequisites needed on your side:
- Make sure you have echo, grep, cut, /bin/date, wget (no SSL needed here) and awk available using the following commands:
- which echo
- which grep
- which cut
- which date
- which wget
- which awk
If you do not have one of these binaries installed, install it w/ opkg.
- Change the LED directory (LEDDIR) in the below script to the LED that you want to use.
(TIP: use the following for a list of system LEDs)
ls -1 /sys/class/leds/
- Make sure your chosen LED is unused during normal day-to-day operations and has a non-zero brightness and a timer trigger. Ex: for me, I'd execute the following:
echo 255 > /sys/class/leds/ht-tm02:blue:wlan/brightness
echo timer > /sys/class/leds/ht-tm02:blue:wlan/trigger
- Make sure your system time is correct by running /bin/date. If it's not correct, sync with an NTP server. Also, I live in CDT, so premarket opens at 04:00, market closes at 15:00 for me. If your timezone is different, you'll want to change the if statement conditions on line 24 in the below script:
if [ $hour -ge 4 ] && [ $hour -le 15 ]; then
#! /bin/sh
#################################
# STOCKLED BLINK ON MOVE
# BY
# Joshua Patterson, PhD
#
# v1.0
#################################
SSymbol=$1
LEDDIR="/sys/class/leds/ht-tm02:blue:wlan"
workDays="Mon Tue Wed Thu Fri"
isOk=0
isOkTime=0
isOkDay=0
echo "STOCKLED service starting..."
while [ true ]; do
dString=$(/bin/date)
day=$(echo $dString | cut -d' ' -f1)
hour=$(echo $dString | cut -d' ' -f4 | cut -d':' -f1 | awk '{printf( "%d\n", $1)}' )
#min=$(echo $dString | cut -d' ' -f4 | cut -d':' -f2 | awk '{printf( "%d\n", $1)}' )
isOkDay=$(echo $workDays | grep -c $day)
if [ $hour -ge 4 ] && [ $hour -le 15 ]; then
isOkTime=1
else
isOkTime=0
fi
isOk=$(echo $isOkDay $isOkTime | awk '{printf( "%d\n", $1*$2)}')
if [ $isOk -ge 1 ]; then
stock_line=$(wget -qO- http://thestockmarketwatch.com/stock/?stock=$SSymbol | grep "$SSymbol</a></td><td class='companyName'>[A-Za-z ,.]*</td><td style=\"width:60px;\"> </td><td style='width:50px;padding:5px;text-align:right;background:rgba([0-9]*,[0-9]*,[0-9]*,[0-9.]*);'>[-0-9.%]*</td><td style='text-align:right;'>[0-9.]*</td><td style='text-align:right;[colred:;]*'>[0-9.%]*</td><td class='hideOnMobile' style='text-align:right;'>[$.0-9kmb]*</td>" -o)
pChange=$(echo $stock_line | grep "background:rgba([0-9]*,[0-9]*,[0-9]*,[0-9.]*);'>[-0-9.]*%" -o | grep -o "[-0-9.]*%$" | grep -o [-0-9.]* | awk '{printf( "%d\n", $1*1000)}' )
#echo $pChange
if [ $pChange -le 0 ]; then
pChangeAbs=$(echo $pChange | grep -o [0-9.]*)
#echo "its < 0 ... $pChange $pChangeAbs"
echo $pChangeAbs > $LEDDIR/delay_off
echo 50 > $LEDDIR/delay_on
else
#echo "its > 0 ... $pChange"
echo $pChange > $LEDDIR/delay_on
echo 50 > $LEDDIR/delay_off
fi
fi
#echo "Sleeping for 600 sec..."
sleep 600
done
Usage
- Simply pass one argument, the stock symbol.
sh /root/stockled.sh AAPL
Installing as a /etc/init.d service
Lastly, for anyone wanting to install it as a /etc/init.d service, I used this script (given below) located in /etc/init.d
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=99
STOP=01
start_service() {
procd_open_instance
procd_set_param command /bin/sh "/root/stockled.sh" AAPL
procd_set_param stdout 1
procd_set_param stderr 1
procd_close_instance
}
You'll want to change the procd_set_param command line to reflect where you placed your initial STOCKLED script and change the stock symbol argument to your stock. You'll also want this file servicename in /etc/init.d to be chmod 777 before enabling the service with:
chmod 777 /etc/init.d/servicename
/etc/init.d/servicename start
/etc/init.d/servicename enable
Ethical Concerns
Network service admins generally hate OpenWRT users using their services in a while loop, so we should be mindful of the number of times we request stock quote data per day. I've set the sleep timer between data requests to 600s (10m) during market/premarket hours to keep the number of data requests down to 72/day which seems reasonable to me for a non-https static webpage displaying live data (i.e. I'd end up refreshing the page > 72 times a day anyway). That said, please be careful if you intend to change these values.
Future Work / Improvements
While it's true we wait 600s (10m) between stock quote requests, this version of the script also waits 600s (10m) before checking the date/time to know if the market is open or not. This leads to 144 /bin/date calls per day. We could reduce this by actually calculating the time until the market opens (if its closed) and act accordingly by sleeping the exact calculated time rather than the current approach.
Conclusion
I hope this is helpful to someone. I enjoy being able to wake up (or roll over in bed @ 4:30am CDT) and glance at my router to know how my stock is doing even if its during the premarket because the regular market hasn't opened yet--if I had more LEDs, I could diversify! #notinvestingadvice