A Gold price voice reporter for macOS

26 Feb 2020

Write a shell program that automatically announce gold price in a specified time period according to the set frequency.

Why I do this?

I have been doing paper gold trading at China Construction Bank, and I have to frequent login the bank's APP to see the gold price, which makes me some trouble.

I hope that a "announcer" can broadcasts gold price regularly. I only open the bank's APP when I think it can be bought or sold. So I analyzed the webpage of the bank's gold quotes, and wrote a shell program to implement this idea.

The program can periodically read the bank's webpage according to my need, and parse out the current gold price, day's highest, lowest and quote change.

Analyze bank's quote web page

CCB provides an online trendchart and required no login, it's convenient for the program to spider the price. The webpage's url is:

http://tool.ccb.com/webtran/static/trendchart/index.html

The data I need is shown in the red box above.

Among them, the large bold font is the latest price(the middle price of gold), the percentage below the arrow is the rate of change for the day, and then there is the lowest and highest price of the day on right.

Setp 1: View page source

Right click and select "View Page Source", open the page's source view:

Here you can find a select control for selecting the type of precious metal and some span label that displays the price. These spans only have an ID but no price data. So I think it should be filling data into these spans through js or ajax.

Step 2: Find the data source

Then I need to sduty the js code or js file referenced on this page.

This page contains a piece of js code that checks browser compatibility, and references to 4 external js files. The last one, trend.js, is easy to tell from the file name that it's dealing with the price. Click the file name and open it:

The first two line of it clearly indicate that p1 is a request connection for realtime quotes, and sec_code is the code of the precious metal type. Press Ctrl and F shortcut, type p1 to query it's assignment(in the second red box above).

Then, stitch the url of this page and the assignment of p1 to get the address of real-time data source. The sec_code can find in the page's source.

http://tool.ccb.com/webtran/static/trendchart/js/getAccountData.gsp?dateType=timeSharing&sec_code=019999

Step 3: Analysis data format

The format of this data source is generally a map data type, including the closing price of previous day, the current time, the real-time prices, the opening price, the rate of change, the highest price, the lowest price and the latest.

The value of the real-time price is a list, which records the time and pirce of each quote.

The data I need is at the end of this big map, so pull the page to the bottom to see it.

Now that I have the required data, I can write program to read it.

The program's code

This program can be written in zsh, get the data through curl command, then intercept the last string contaning the data I need, and then parse out the prices one by one. Finally, use macOS's say command turn text into sound.

1
#!/bin/zsh
2
START_HOUR=7
3
END_HOUR=21
4
INTERVAL_TIME=1190
5
while true
6
do
7
    nowtime=`date +%H`
8
    if [[ "$nowtime" -ge "$START_HOUR" && "$nowtime" -le "$END_HOUR" ]]; then
9
        last_line=$(curl "http://tool.ccb.com/webtran/static/trendchart/getAccountData.gsp?dateType=timeSharing&sec_code=019999" -s)
10
        last_line=($last_line[-112,-2])
11
        last_line=(${last_line//\"})
12
        last_line=(${last_line//\,/\ })
13
        prices=(${=last_line})
14
        price=$prices[1]
15
        ope_price=($price[$price[(i):]+1,-1])
16
        price=$prices[2]
17
        chg_price=($price[$price[(i):]+1,-1])
18
        price=$prices[3]
19
        hig_price=($price[$price[(i):]+1,-1])
20
        price=$prices[5]
21
        low_price=($price[$price[(i):]+1,-1])
22
        price=$prices[6]
23
        now_price=($price[$price[(i):]+1,-1])
24
        echo "-----------------------------"
25
        echo $(date)
26
        echo "Current:" $now_price
27
        echo "Change:" $chg_price
28
        echo "Today's highest:" $hig_price
29
        echo "Lowest:" $low_price
30
        say "Attention please, gold price report now:"
31
        say "Current:"
32
        say $now_price
33
        say $now_price
34
        say "Today's highest:"
35
        say $hig_price
36
        say "lowest:"
37
        say $low_price
38
        say "That's all."
39
    fi
40
    sleep $INTERVAL_TIME
41
done

Download and Use

I named this program gold, you can click here to download if you need.

This program can only be used under macOS. If you want to run on other systems that support zsh, you need to replace the say command with other command provided by your system.

To use it under macOS:

1. Open a terminal and change to the directory where gold is located.

2. Execute chmod +x gold to make the program executable.

3. Type in ./gold and press Enter key. If you want to run it in the background, you can add an & after.

4. You can also create a soft link sudo ln -s your_path/gold /usr/local/bin/gold. Just execute gold & in the terminal.

I set it run every 20 minutes from 7 am to 9pm. If you need to change it, you can open the program with vim or any other text editor, and modify the START_HOUR, END_HOUR and INTERVAL_TIME variables. The unit of INTERVAL_TIME is second.