Compare commits
5 Commits
ab75694176
...
c77ebd10ff
| Author | SHA1 | Date | |
|---|---|---|---|
| c77ebd10ff | |||
| cae388ac91 | |||
| 85362cacda | |||
| 8fa59c9846 | |||
| d381eb8043 |
447
cryptos.sh
Executable file
447
cryptos.sh
Executable file
@@ -0,0 +1,447 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#set -e
|
||||||
|
|
||||||
|
### https://coinmarketcap.com/api/documentation/v1/#operation/getV2CryptocurrencyQuotesLatest
|
||||||
|
|
||||||
|
VERSION="v1.0"
|
||||||
|
|
||||||
|
### TODO
|
||||||
|
# Locale compliant
|
||||||
|
# Localization
|
||||||
|
|
||||||
|
redbold="\033[1;31m"
|
||||||
|
red="\033[0;31m"
|
||||||
|
greenbold="\033[1;32m"
|
||||||
|
green="\033[0;32m"
|
||||||
|
yellowbold="\033[1;33m"
|
||||||
|
yellow="\033[0;33m"
|
||||||
|
|
||||||
|
bgd="\033[1;4;31m"
|
||||||
|
|
||||||
|
bold="\033[1m"
|
||||||
|
#bold_under="\033[1;4m"
|
||||||
|
italic="\033[3m"
|
||||||
|
ita_under="\033[3;4m"
|
||||||
|
underline="\033[4m"
|
||||||
|
|
||||||
|
reset="\033[0m"
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
ScriptArgs=( "$@" )
|
||||||
|
ScriptPath="$(readlink -f "$0")" # /Users/user/Documents/Scripts/stocks/crypto.sh
|
||||||
|
ScriptWorkDir="$(dirname "$ScriptPath")" # /Users/user/Documents/Scripts/stocks
|
||||||
|
|
||||||
|
|
||||||
|
####### Configurations ######
|
||||||
|
|
||||||
|
### Credentials
|
||||||
|
### Put the CMC_API_KEY= in .env file
|
||||||
|
dotenv () {
|
||||||
|
set -a
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
[ -f "$ScriptWorkDir/.env" ] && . "$ScriptWorkDir/.env" || echo -e "${red}\nNo .env file found ! CMC_API_KEY needed !!${reset}"
|
||||||
|
set +a
|
||||||
|
}
|
||||||
|
dotenv
|
||||||
|
|
||||||
|
### or in the script
|
||||||
|
#CMC_API_KEY=
|
||||||
|
|
||||||
|
if [ -z $CMC_API_KEY ]; then
|
||||||
|
echo -e "\n${red}No CMC_API_KEY key found !${reset}"
|
||||||
|
help
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
### Config file
|
||||||
|
cryptos_list=$HOME/.cryptos.yaml
|
||||||
|
|
||||||
|
# Free version does not support more than 1 currency.
|
||||||
|
# So, 2 requests for Euro and Dollar exchange rates
|
||||||
|
# Default currency (MUST BE THE SAME as unit_cost in ~/.cryptos.yaml)
|
||||||
|
currency="EUR"
|
||||||
|
symb_currency="€"
|
||||||
|
# Secondary currency (optionnal)
|
||||||
|
currency2="USD"
|
||||||
|
symb_currency2="$"
|
||||||
|
|
||||||
|
color_display=true # (true/false)
|
||||||
|
####### /Configurations ######
|
||||||
|
|
||||||
|
|
||||||
|
### Requierements
|
||||||
|
if ! $(type jq >/dev/null 2>&1); then
|
||||||
|
echo -e "${red}'jq' is not in the PATH. (See: https://stedolan.github.io/jq/)${reset}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! $(type yq >/dev/null 2>&1); then
|
||||||
|
echo -e "${red}'yq' is not in the PATH. (See: https://github.com/kislyuk/yq)${reset}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat < /dev/null > /dev/tcp/1.1.1.1/53
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo -e "\n${red}No Internet connection !${reset}"
|
||||||
|
echo -e "Exit !"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
####### Functions ######
|
||||||
|
|
||||||
|
# Help
|
||||||
|
Help() {
|
||||||
|
echo -e "${bold}cryptos $VERSION${reset}\n"
|
||||||
|
echo "Syntax: cryptos.sh [<coin>]"
|
||||||
|
echo
|
||||||
|
echo "Examples: cryptos.sh BTC ETH SOLE"
|
||||||
|
echo " cryptos.sh (need ~/.cryptos.yaml file)"
|
||||||
|
echo
|
||||||
|
echo "Options:"
|
||||||
|
echo "-h Print this Help."
|
||||||
|
echo
|
||||||
|
echo "Requires a CoinMarketCap API key"
|
||||||
|
echo "https://coinmarketcap.com/api/"
|
||||||
|
echo "Requires jq and yq installed"
|
||||||
|
echo
|
||||||
|
echo "\$currency variable (default)(line 39) must be the same as unit_cost in ~/.cryptos.yaml"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if number is positive (or 0) or negative
|
||||||
|
CheckSign() {
|
||||||
|
local n="$1" # Capture the number passed as a parameter.
|
||||||
|
|
||||||
|
if [ $(echo "$n < 0" | bc -l) -eq 1 ] ; then
|
||||||
|
#printf "%+17.13f : %s\n" "$n" "negative"
|
||||||
|
p="-"
|
||||||
|
else
|
||||||
|
#printf "%+17.13f : %s\n" "$n" "positive or zero"
|
||||||
|
p="+"
|
||||||
|
fi
|
||||||
|
echo "$p"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LANG=C
|
||||||
|
LC_NUMERIC=C
|
||||||
|
|
||||||
|
### API
|
||||||
|
URLPREFIX="https://"
|
||||||
|
URLBASE="pro-api.coinmarketcap.com/"
|
||||||
|
URLPOSTFIX="v1/cryptocurrency/"
|
||||||
|
DATAURL=${URLPREFIX}${URLBASE}${URLPOSTFIX}
|
||||||
|
|
||||||
|
|
||||||
|
### Load (or download) a list of existing cryptos
|
||||||
|
|
||||||
|
#list_coins=$(curl --silent -H "X-CMC_PRO_API_KEY: $CMC_API_KEY" -H "Accept: application/json" -d "start=1&limit=5&convert=USD" -G "${DATAURL}listings"/latest)
|
||||||
|
#echo "$list_coins" | jq -r '.data[].name, .data[].symbol'
|
||||||
|
#echo "$list_coins" | jq -r '.data[] | {name: .name, symbol: .symbol}'
|
||||||
|
|
||||||
|
#list_coins=$(curl --silent -H "X-CMC_PRO_API_KEY: $CMC_API_KEY" -H "Accept: application/json" -d "start=1&limit=5&convert=USD" -G "${DATAURL}listings"/latest | jq -r '.data[] | .symbol')
|
||||||
|
|
||||||
|
get_list_coins (){
|
||||||
|
START_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
curl --silent -H "X-CMC_PRO_API_KEY: $CMC_API_KEY" -H "Accept: application/json" -d "start=1&limit=5000&convert=USD" -G "${DATAURL}listings"/latest | jq -r '.data[] | .symbol' > "$ScriptWorkDir/list_coins.txt"
|
||||||
|
status=$?
|
||||||
|
END_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
ELAPSED_TIME=$(($END_TIME - $START_TIME))
|
||||||
|
[ $status -eq 0 ] && echo -e "${green}Request to CMC API listings $currency successfull in $ELAPSED_TIME ms !${reset}" || echo -e "${red}Request to CMC API listing $currency failed !${reset}"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo -e "${greenbold}Bash Crypto${reset} $VERSION"
|
||||||
|
echo -e "Using CoinMarketCap API ($DATAURL)\n"
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f "$ScriptWorkDir/list_coins.txt" ]; then
|
||||||
|
|
||||||
|
timestamp_current=$(date +"%s")
|
||||||
|
timestamp_file=$(date -r list_coins.txt +"%s")
|
||||||
|
since=$(($((timestamp_current - timestamp_file))/(60*60*24)))
|
||||||
|
|
||||||
|
# Re-Download coins list every 15 days
|
||||||
|
((since > 15)) && { echo -e "${green}Download coins list...${reset}"; get_list_coins; }
|
||||||
|
list_coins=$(cat "$ScriptWorkDir/list_coins.txt")
|
||||||
|
[ $? -eq 0 ] && echo -e "${green}Load coins list...${reset}" || echo -e "${red}Fail to load coins list...${reset}"
|
||||||
|
else
|
||||||
|
|
||||||
|
get_list_coins
|
||||||
|
list_coins=$(cat "$ScriptWorkDir/list_coins.txt")
|
||||||
|
[ $? -eq 0 ] && echo -e "${green}Load coins list...${reset}" || echo -e "${red}Fail to load coins list...${reset}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
### Read cryptos from ~/.cryptos.yaml config file
|
||||||
|
cryptos=()
|
||||||
|
|
||||||
|
# from arguments
|
||||||
|
if [ -n "$ScriptArgs" ]; then
|
||||||
|
|
||||||
|
REGEXP='^[a-zA-Z0-9,_ ]+$'
|
||||||
|
q="$@"
|
||||||
|
if [[ "$q" =~ $REGEXP ]]; then
|
||||||
|
q=${q//,/\ }
|
||||||
|
q=${q//_/\ }
|
||||||
|
|
||||||
|
cryptos+=($q)
|
||||||
|
else
|
||||||
|
Help
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if crypto passed as argument really exist
|
||||||
|
for val in ${!cryptos[@]}
|
||||||
|
do
|
||||||
|
k="${cryptos[$val]}"
|
||||||
|
|
||||||
|
#echo $val # index
|
||||||
|
#echo $k # value
|
||||||
|
|
||||||
|
if [[ ! "$list_coins" == *"$k"* ]]; then
|
||||||
|
echo -e "${red}$k is not a crypto. Remove it !${reset}"
|
||||||
|
unset cryptos[$val]
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Recreate the array, because the gaps have to disappear
|
||||||
|
cryptos=("${cryptos[@]}")
|
||||||
|
echo -e "${green}Found ${#cryptos[@]} coins to display: ${cryptos[@]} ...${reset}"
|
||||||
|
|
||||||
|
# from ~/.cryptos.yaml config file
|
||||||
|
else
|
||||||
|
|
||||||
|
if [ -f "$cryptos_list" ]; then
|
||||||
|
cl=$(cat $cryptos_list)
|
||||||
|
a=$(yq '.watchlist' <<< $cl)
|
||||||
|
#a=$(cat $cryptos_list | yq '.watchlist') # Cryptos to display
|
||||||
|
status=$?
|
||||||
|
#[ $? -eq 0 ] && echo -e "${green}Load coins list to display...${reset}" || echo -e "${red}Fail to load coins list to display...${reset}"
|
||||||
|
b=$(yq '.lot' <<< $cl)
|
||||||
|
#b=$(cat $cryptos_list | yq '.lots') # Cryptos i've purchased
|
||||||
|
c=$((yq '.lots[] | select(.quantity != 0) | .symbol' | tr '\n' ' ') <<< $cl)
|
||||||
|
#c=$(cat $cryptos_list | yq '.lots[] | select(.quantity != 0) | .symbol' | tr '\n' ' ')
|
||||||
|
u=$(echo "$c" | wc -w)
|
||||||
|
|
||||||
|
[ $? -eq 0 ] && echo -e "${green}Found $u coins purchased: $c ...${reset}" || echo -e "${red}Fail to load coins list purchased...${reset}"
|
||||||
|
else
|
||||||
|
echo -e "${red}$cryptos_list not present !${reset}"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
while IFS= read -r obj; do
|
||||||
|
stock=${obj:2}
|
||||||
|
cryptos+=("$stock")
|
||||||
|
done < <(echo "$a")
|
||||||
|
[ $status -eq 0 ] && echo -e "${green}Found ${#cryptos[@]} coins to display: ${cryptos[@]} ...${reset}" || echo -e "${red}No coins to display...${reset}"
|
||||||
|
|
||||||
|
if [ -z "$cryptos" ]; then
|
||||||
|
echo "Usage: ./crypto.sh"
|
||||||
|
echo " - add coins to ~/.cryptos.yaml file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
nb_cryptos=${#cryptos[@]}
|
||||||
|
symbols=$(echo ${cryptos[@]} | tr [:space:] ',' | awk '{ print substr( $0, 1, length($0)-1 ) }')
|
||||||
|
|
||||||
|
|
||||||
|
# Free version does not support more than 1 currency.
|
||||||
|
# So, 2 requests for Euro and Dollar exchange rates
|
||||||
|
|
||||||
|
if [ -n "$currency2" ]; then
|
||||||
|
# 2 currency
|
||||||
|
START_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
request=$(curl --silent -H "X-CMC_PRO_API_KEY: $CMC_API_KEY" -H "Accept: application/json" -d "convert=$currency" -G "${DATAURL}quotes"/latest?symbol=$symbols)
|
||||||
|
status=$?
|
||||||
|
END_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
ELAPSED_TIME=$(($END_TIME - $START_TIME))
|
||||||
|
[ $status -eq 0 ] && echo -e "${green}Request to CMC API with currency $currency successfull in $ELAPSED_TIME ms !${reset}" || echo -e "${red}Request to CMC API with currency $currency failed !${reset}"
|
||||||
|
|
||||||
|
START_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
request2=$(curl --silent -H "X-CMC_PRO_API_KEY: $CMC_API_KEY" -H "Accept: application/json" -d "convert=$currency2" -G "${DATAURL}quotes"/latest?symbol=$symbols)
|
||||||
|
status2=$?
|
||||||
|
END_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
ELAPSED_TIME=$(($END_TIME - $START_TIME))
|
||||||
|
[ $status2 -eq 0 ] && echo -e "${green}Request to CMC API with currency $currency2 successfull in $ELAPSED_TIME ms !${reset}" || echo -e "${red}Request to CMC API with currency $currency2 failed !${reset}"
|
||||||
|
|
||||||
|
echo -e "${green}Displaying quotes for ${cryptos[@]} ...${reset}\n"
|
||||||
|
printf "${bold}| %-15s | %-4s | %-9s | %-9s | %-14s | %-7s | %-7s | %-7s | %-7s | %-7s | %-25s ${reset}\n" "Nom" "Symb" " Prix ($symb_currency)" " Prix ($symb_currency2)" " Volume" " % 24h" " % 7j" " % 30j" " % 60j" " % 90j" "Dernière mise-à-jour"
|
||||||
|
printf "${bold}%141s${reset}\n" " " | tr ' ' '-'
|
||||||
|
else
|
||||||
|
# 1 currency
|
||||||
|
START_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
request=$(curl --silent -H "X-CMC_PRO_API_KEY: $CMC_API_KEY" -H "Accept: application/json" -d "convert=$currency" -G "${DATAURL}quotes"/latest?symbol=$symbols)
|
||||||
|
status=$?
|
||||||
|
END_TIME=`echo $(($(date +%s%N)/1000000))`
|
||||||
|
ELAPSED_TIME=$(($END_TIME - $START_TIME))
|
||||||
|
[ $status -eq 0 ] && echo -e "${green}Request to CMC API with currency $currency successfull in $ELAPSED_TIME ms !${reset}" || echo -e "${red}Request to CMC API with currency $currency failed !${reset}"
|
||||||
|
|
||||||
|
echo -e "${green}Displaying quotes for ${cryptos[@]} ...${reset}\n"
|
||||||
|
printf "${bold}| %-15s | %-4s | %-9s | %-14s | %-7s | %-7s | %-7s | %-7s | %-7s | %-25s ${reset}\n" "Nom" "Symb" " Prix ($symb_currency)" " Volume" " % 24h" " % 7j" " % 30j" " % 60j" " % 90j" "Dernière mise-à-jour"
|
||||||
|
printf "${bold}%141s${reset}\n" " " | tr ' ' '-'
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Check if NO_COLOR is set to disable colorization
|
||||||
|
if [ -z "$NO_COLOR" ]; then
|
||||||
|
: "${COLOR_GREEN:=$'\e[32m'}"
|
||||||
|
: "${COLOR_RED:=$'\e[31m'}"
|
||||||
|
: "${COLOR_RESET:=$'\e[00m'}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#b=$(cat $cryptos_list | yq '.lots')
|
||||||
|
#echo "$b"
|
||||||
|
#d=$(cat $cryptos_list | yq '.lots[]')
|
||||||
|
#echo "$d"
|
||||||
|
#c=$(cat $cryptos_list | yq '.lots[] | select(.quantity != 0) | .symbol')
|
||||||
|
|
||||||
|
counter=0
|
||||||
|
while [ $counter -lt $nb_cryptos ]; do
|
||||||
|
|
||||||
|
c=$(echo "${cryptos[counter]}")
|
||||||
|
filter=".$c"
|
||||||
|
#echo "value (crypto): $c"
|
||||||
|
|
||||||
|
# devise 1 (EUR)
|
||||||
|
coin=$(echo "$request" | jq -r '.data' | jq -r $filter)
|
||||||
|
|
||||||
|
if [ "$coin" == null ]; then
|
||||||
|
echo -e "${red}$c n'est pas une crypto !${reset}"
|
||||||
|
((counter++))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
name=$(echo "$coin" | jq -r '.name')
|
||||||
|
symbol=$(echo "$coin" | jq -r '.symbol')
|
||||||
|
slug=$(echo "$coin" | jq -r '.slug')
|
||||||
|
|
||||||
|
max_supply=$(echo "$coin" | jq -r '.max_supply') # Volume (Mrd) ($2,07 Mrd)
|
||||||
|
circulating_supply=$(echo "$coin" | jq -r '.circulating_supply') # Supply en circulation (Mio BNB) (144,01 Mio BNB)
|
||||||
|
total_supply=$(echo "$coin" | jq -r '.total_supply') # Montant total fourni (Mio BNB) (144,01 Mio BNB)
|
||||||
|
cmc_rank=$(echo "$coin" | jq -r '.cmc_rank') # Rang (N°5)
|
||||||
|
|
||||||
|
filter2=".$currency"
|
||||||
|
quote=$(echo "$coin" | jq -r '.quote'| jq -r $filter2)
|
||||||
|
price=$(echo "$quote" | jq -r '.price')
|
||||||
|
volume_24h=$(echo "$quote" | jq -r '.volume_24h')
|
||||||
|
percent_change_24h=$(echo "$quote" | jq -r '.percent_change_24h')
|
||||||
|
percent_change_7d=$(echo "$quote" | jq -r '.percent_change_7d')
|
||||||
|
percent_change_30d=$(echo "$quote" | jq -r '.percent_change_30d')
|
||||||
|
percent_change_60d=$(echo "$quote" | jq -r '.percent_change_60d')
|
||||||
|
percent_change_90d=$(echo "$quote" | jq -r '.percent_change_90d')
|
||||||
|
last_updated=$(echo "$quote" | jq -r '.last_updated') # 2025-01-07T16:35:00.000Z UTC (ZULU)
|
||||||
|
last_updated_fr=$(date --date="$last_updated" +"%d/%m/%Y %H:%M:%S %Z")
|
||||||
|
|
||||||
|
market_cap=$(echo "$quote" | jq -r '.market_cap') # Capitalisation (Mrd) ($103,47 Mrd ~= €95,81 Mrd)
|
||||||
|
market_cap_dominance=$(echo "$quote" | jq -r '.market_cap_dominance') # Dominance sur le marché (%) (2,94%)
|
||||||
|
fully_diluted_market_cap=$(echo "$quote" | jq -r '.fully_diluted_market_cap') # Cap. du marché totlalement diluée (Mrd) ($103,47 Mrd ~= €95,81 Mrd)
|
||||||
|
|
||||||
|
|
||||||
|
# devise 2 (USD)
|
||||||
|
if [ -n "$currency2" ]; then
|
||||||
|
coin2=$(echo "$request2" | jq -r '.data' | jq -r $filter)
|
||||||
|
filter3=".$currency2"
|
||||||
|
quote2=$(echo "$coin2" | jq -r '.quote' | jq -r $filter3)
|
||||||
|
price2=$(echo "$quote2" | jq -r '.price')
|
||||||
|
fi
|
||||||
|
|
||||||
|
: <<'END_COMMENT'
|
||||||
|
blabla
|
||||||
|
END_COMMENT
|
||||||
|
|
||||||
|
# Check cryptos we have (from .cryptos.yaml)
|
||||||
|
|
||||||
|
z=$(cat $cryptos_list | yq '.lots[] | select(.symbol == "'${c}'")')
|
||||||
|
|
||||||
|
### OK ###
|
||||||
|
#z=$(yq '.[] | select(.symbol == "'${c}'")' <<< "$b")
|
||||||
|
#echo "z: $z"
|
||||||
|
|
||||||
|
if [ ! -z "$z" ]; then
|
||||||
|
quantity=$(yq '.quantity' <<< $z)
|
||||||
|
else
|
||||||
|
quantity=0
|
||||||
|
fi
|
||||||
|
### /OK ###
|
||||||
|
|
||||||
|
# Côté variables
|
||||||
|
#COLOR_24h=$([ $(CheckSign "$percent_change_24h") == "+" ] && echo ${COLOR_GREEN} || echo ${COLOR_RED})
|
||||||
|
#COLOR_7d=$([ $(CheckSign "$percent_change_7d") == "+" ] && echo ${COLOR_GREEN} || echo ${COLOR_RED})
|
||||||
|
#COLOR_30d=$([ $(CheckSign "$percent_change_30d") == "+" ] && echo ${COLOR_GREEN} || echo ${COLOR_RED})
|
||||||
|
#COLOR_60d=$([ $(CheckSign "$percent_change_60d") == "+" ] && echo ${COLOR_GREEN} || echo ${COLOR_RED})
|
||||||
|
#COLOR_90d=$([ $(CheckSign "$percent_change_90d") == "+" ] && echo ${COLOR_GREEN} || echo ${COLOR_RED})
|
||||||
|
|
||||||
|
# Côté mise-en-page
|
||||||
|
COLOR_24h=$([ $(CheckSign "$percent_change_24h") == "+" ] && echo ${green} || echo ${red})
|
||||||
|
COLOR_7d=$([ $(CheckSign "$percent_change_7d") == "+" ] && echo ${green} || echo ${red})
|
||||||
|
COLOR_30d=$([ $(CheckSign "$percent_change_30d") == "+" ] && echo ${green} || echo ${red})
|
||||||
|
COLOR_60d=$([ $(CheckSign "$percent_change_60d") == "+" ] && echo ${green} || echo ${red})
|
||||||
|
COLOR_90d=$([ $(CheckSign "$percent_change_90d") == "+" ] && echo ${green} || echo ${red})
|
||||||
|
|
||||||
|
|
||||||
|
if [ -n "$currency2" ]; then
|
||||||
|
# 2 currency
|
||||||
|
if [ "$color_display" == true ];then
|
||||||
|
# With % colors
|
||||||
|
printf "${yellowbold}| %-15s | %-4s | %'9.2f | %'9.2f | %'14d |${reset}${COLOR_24h} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_7d} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_30d} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_60d} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_90d} %+6.1f%% ${COLOR_RESET}${yellowbold}| %-25s ${reset}\n" \
|
||||||
|
"$name" "$symbol" "$price" "$price2" "$volume_24h" "$percent_change_24h" "$percent_change_7d" "$percent_change_30d" "$percent_change_60d" "$percent_change_90d" "$last_updated_fr" 2>/dev/null
|
||||||
|
else
|
||||||
|
# Without colors
|
||||||
|
printf "| %-15s | %-4s | %'9.2f | %'9.2f | %'14d | %+6.1f%% | %+6.1f%% | %+6.1f%% | %+6.1f%% | %+6.1f%% | %-25s \n" "$name" "$symbol" "$price" "$price2" "$volume_24h" "$percent_change_24h" "$percent_change_7d" "$percent_change_30d" "$percent_change_60d" "$percent_change_90d" "$last_updated_fr" 2>/dev/null
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# 1 currency
|
||||||
|
if [ "$color_display" == true ];then
|
||||||
|
# With % colors
|
||||||
|
printf "${yellowbold}| %-15s | %-4s | %'9.2f | %'14d |${reset}${COLOR_24h} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_7d} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_30d} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_60d} %+6.1f%% ${COLOR_RESET}${yellowbold}|${COLOR_RESET}${COLOR_90d} %+6.1f%% ${COLOR_RESET}${yellowbold}| %-25s ${reset}\n" \
|
||||||
|
"$name" "$symbol" "$price" "$volume_24h" "$percent_change_24h" "$percent_change_7d" "$percent_change_30d" "$percent_change_60d" "$percent_change_90d" "$last_updated_fr" 2>/dev/null
|
||||||
|
else
|
||||||
|
# Without colors
|
||||||
|
printf "| %-15s | %-4s | %'9.2f | %'14d | %+6.1f%% | %+6.1f%% | %+6.1f%% | %+6.1f%% | %+6.1f%% | %-25s \n" "$name" "$symbol" "$price" "$volume_24h" "$percent_change_24h" "$percent_change_7d" "$percent_change_30d" "$percent_change_60d" "$percent_change_90d" "$last_updated_fr" 2>/dev/null
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
: <<'END_COMMENT2'
|
||||||
|
END_COMMENT2
|
||||||
|
|
||||||
|
if (( $(bc <<< "$quantity > 0") )); then
|
||||||
|
|
||||||
|
quantity=$(yq '.quantity' <<<$z)
|
||||||
|
unit_cost=$(yq '.unit_cost' <<<$z) # EUR
|
||||||
|
purchased=$(echo "$quantity * $unit_cost" | bc -l)
|
||||||
|
valuations=$(echo "$quantity * $price" | bc -l)
|
||||||
|
profit=$(echo "$valuations - $purchased" | bc -l)
|
||||||
|
performance=$(echo "($valuations / $purchased - 1) * 100" | bc -l)
|
||||||
|
|
||||||
|
# quantity -> Disponible
|
||||||
|
# unit_cost -> Coût moyen
|
||||||
|
# purchased -> Acheté
|
||||||
|
# valuations -> Valoris.
|
||||||
|
# profit -> +/- value
|
||||||
|
# performance -> Perf.
|
||||||
|
|
||||||
|
printf "| %-11s | %-9s | %-10s | %-9s | %-9s | %-8s \n" "Disponible" "Coût moyen" "Acheté" "Valoris." "+/- value" "Perf." 2>/dev/null
|
||||||
|
|
||||||
|
if (( $(bc <<< "$performance > 0") )); then
|
||||||
|
printf "${green}| %11s | %10.2f | %9.2f | %9.2f | %9.2f | %8.2f%% ${reset}\n\n" "$quantity" "$unit_cost" "$purchased" "$valuations" "$profit" "$performance" 2>/dev/null
|
||||||
|
else
|
||||||
|
printf "${red}| %11s | %10.2f | %9.2f | %9.2f | %9.2f | %8.2f%% ${reset}\n\n" "$quantity" "$unit_cost" "$purchased" "$valuations" "$profit" "$performance" 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
quantity=0
|
||||||
|
unit_cost=0
|
||||||
|
purchased=0
|
||||||
|
valuations=0
|
||||||
|
profit=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
((counter++))
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e "\n${italic}Script finished in $SECONDS seconds.${reset}"
|
||||||
5000
list_coins.txt
Normal file
5000
list_coins.txt
Normal file
File diff suppressed because it is too large
Load Diff
14
loader.sh
Executable file
14
loader.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
### Variables for self updating
|
||||||
|
ScriptArgs=( "$@" )
|
||||||
|
ScriptPath="$(readlink -f "$0")" # /Users/user/Documents/Scripts/stocks/crypto.sh
|
||||||
|
ScriptWorkDir="$(dirname "$ScriptPath")" # /Users/user/Documents/Scripts/stocks
|
||||||
|
|
||||||
|
|
||||||
|
$ScriptWorkDir/stocks.sh
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
|
||||||
|
$ScriptWorkDir/cryptos.sh
|
||||||
36
purchased.json
Normal file
36
purchased.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"quotes": [
|
||||||
|
{
|
||||||
|
"symbol": "ALCLS.PA",
|
||||||
|
"price": "1.74",
|
||||||
|
"volume": "35596",
|
||||||
|
"last": "1736786105",
|
||||||
|
"symb": "€",
|
||||||
|
"percent": "-2.36"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"symbol": "AUB.PA",
|
||||||
|
"price": "44.35",
|
||||||
|
"volume": "3166",
|
||||||
|
"last": "1736786126",
|
||||||
|
"symb": "€",
|
||||||
|
"percent": "-1.44"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"symbol": "GOOG",
|
||||||
|
"price": "190.81",
|
||||||
|
"volume": "6494394",
|
||||||
|
"last": "1736789006",
|
||||||
|
"symb": "$",
|
||||||
|
"percent": "-1.22"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"symbol": "ORA.PA",
|
||||||
|
"price": "9.826",
|
||||||
|
"volume": "5715409",
|
||||||
|
"last": "1736786117",
|
||||||
|
"symb": "€",
|
||||||
|
"percent": "1.17"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
579
stocks.sh
579
stocks.sh
@@ -1,181 +1,476 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
italic="\033[3m"
|
# MIT License
|
||||||
underline="\033[4m"
|
# forked from https://github.com/appatalks/ticker.sh
|
||||||
ita_under="\033[3;4m"
|
# original script https://github.com/pstadler/ticker.sh
|
||||||
bgd="\033[1;4;31m"
|
|
||||||
red="\033[1;31m"
|
VERSION="v1.0"
|
||||||
green="\033[1;32m"
|
|
||||||
bold="\033[1m"
|
### TODO
|
||||||
box="\033[1;41m"
|
# Verif stocks in $@
|
||||||
reset="\033[0m"
|
# Locale compliant
|
||||||
|
# Localization
|
||||||
|
|
||||||
|
|
||||||
|
### API
|
||||||
|
: ${TMPDIR:=/tmp}
|
||||||
|
SESSION_DIR="${TMPDIR%/}/ticker.sh-$(whoami)"
|
||||||
|
COOKIE_FILE="${SESSION_DIR}/cookies.txt"
|
||||||
|
API_ENDPOINT="https://query1.finance.yahoo.com/v8/finance/chart/"
|
||||||
|
API_SUFFIX="?interval=1d"
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
ScriptArgs=( "$@" )
|
||||||
|
ScriptPath="$(readlink -f "$0")" # /Users/user/Documents/Scripts/stocks/crypto.sh
|
||||||
|
ScriptWorkDir="$(dirname "$ScriptPath")" # /Users/user/Documents/Scripts/stocks
|
||||||
|
|
||||||
|
|
||||||
|
####### Configurations ######
|
||||||
|
|
||||||
|
#NO_COLOR=1
|
||||||
|
|
||||||
LANG=C
|
LANG=C
|
||||||
LC_NUMERIC=C
|
LC_NUMERIC=C
|
||||||
|
|
||||||
stocks_list=~/.stocks.yaml
|
# Check if NO_COLOR is set to disable colorization
|
||||||
|
if [ -z "$NO_COLOR" ]; then
|
||||||
query() {
|
: "${COLOR_GREEN:=$'\e[32m'}"
|
||||||
echo "$obj" | jq -r ".$1"
|
: "${COLOR_GREEN_BOLD:=$'\e[1;32m'}"
|
||||||
}
|
: "${COLOR_RED:=$'\e[31m'}"
|
||||||
|
: "${COLOR_RED_BOLD:=$'\e[1;31m'}"
|
||||||
round() {
|
: "${COLOR_YELLOW=$'\e[33m'}"
|
||||||
echo $(printf %.$2f $(echo "scale=$2;(((10^$2)*$1)+0.5)/(10^$2)" | bc))
|
: "${COLOR_YELLOW_BOLD:=$'\e[1;33m'}"
|
||||||
}
|
: "${COLOR_SILVER=$'\e[37m'}"
|
||||||
|
: "${COLOR_LIGHT_GREY=$'\e[249m'}"
|
||||||
# Test if jq & yq executables are in $PATH
|
: "${COLOR_BRIGHT_PURPLE=$'\e[35;1m'}"
|
||||||
|
: "${BOLD:=$'\e[1m'}"
|
||||||
if ! $(type jq >/dev/null 2>&1); then
|
: "${ITALIC:=$'\e[3m'}"
|
||||||
echo "'jq' is not in the PATH. (See: https://stedolan.github.io/jq/)"
|
: "${COLOR_RESET:=$'\e[00m'}"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! $(type yq >/dev/null 2>&1); then
|
|
||||||
echo "'yq' is not in the PATH. (See: https://github.com/kislyuk/yq"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Read stocks from .stocks.yaml config file
|
|
||||||
|
|
||||||
if [ -f $stocks_list ]; then
|
|
||||||
#a=$(cat ~/.stocks.yaml | yq '.watchlist')
|
|
||||||
a=$(cat $stocks_list | yq '.watchlist')
|
|
||||||
b=$(cat $stocks_list | yq '.lots')
|
|
||||||
else
|
else
|
||||||
echo "$stocks_list not present !"
|
: "${BOLD:=$'\e[1m'}"
|
||||||
echo ""
|
: "${COLOR_RESET:=$'\e[00m'}"
|
||||||
|
: "${ITALIC:=$'\e[3m'}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while IFS= read -r obj; do
|
|
||||||
stock=${obj:2}
|
|
||||||
list+="$stock,"
|
|
||||||
done < <(echo "$a")
|
|
||||||
|
|
||||||
symbols=$(echo "$list" | sed 's/.$//')
|
# Help
|
||||||
|
Help() {
|
||||||
|
clear
|
||||||
|
echo -e "\n${COLOR_GREEN_BOLD}Bash Stocks $VERSION${COLOR_RESET}\n"
|
||||||
|
echo "Syntax: stocks.sh [<stock>]"
|
||||||
|
echo
|
||||||
|
echo "Examples: stocks.sh AAPL ORA.PA AUB.PA"
|
||||||
|
echo " stocks.sh (need ~/.stocks.yaml file)"
|
||||||
|
echo
|
||||||
|
echo "Options:"
|
||||||
|
echo "-h Print this Help."
|
||||||
|
echo
|
||||||
|
echo "Requires jq and yq installed"
|
||||||
|
echo " -https://stedolan.github.io/jq/"
|
||||||
|
echo " -https://github.com/kislyuk/yq"
|
||||||
|
}
|
||||||
|
|
||||||
# AC.PA ATO.PA AUB.PA CS.PA DG.PA ^FCHI VIRP.PA WLN.PA
|
### Parse options
|
||||||
|
|
||||||
#####
|
while getopts "h" opt; do
|
||||||
|
case ${opt} in
|
||||||
|
h|*) Help
|
||||||
|
Help
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND -1))
|
||||||
|
|
||||||
if [ -z "$symbols" ]; then
|
|
||||||
echo "Usage: ./stocks.sh"
|
### Config file
|
||||||
echo " - add stocks to ~/.stocks.yaml file"
|
stocks_list=$HOME/.stocks.yaml
|
||||||
exit
|
#json_file="/tmp/purchased.json"
|
||||||
|
json_file="$ScriptWorkDir/purchased.json"
|
||||||
|
#json_file=""
|
||||||
|
|
||||||
|
####### /Configurations ######
|
||||||
|
|
||||||
|
|
||||||
|
### Requierements
|
||||||
|
if ! $(type jq >/dev/null 2>&1); then
|
||||||
|
echo -e "${COLOR_RED}'jq' is not in the PATH. (See: https://stedolan.github.io/jq/)${COLOR_RESET}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! $(type yq >/dev/null 2>&1); then
|
||||||
|
echo -e "${COLOR_RED}'yq' is not in the PATH. (See: https://github.com/kislyuk/yq)${COLOR_RESET}"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get stocks data from yahoo finance
|
cat < /dev/null > /dev/tcp/1.1.1.1/53
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo -e "\n${COLOR_RED}No Internet connection !${COLOR_RESET}"
|
||||||
|
echo -e "Exit !"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
API_ENDPOINT="https://query1.finance.yahoo.com/v7/finance/quote?lang=fr-FR®ion=FR&corsDomain=finance.yahoo.com"
|
|
||||||
|
|
||||||
results=$(curl --silent "$API_ENDPOINT&fields=$fields&symbols=$symbols" | jq '.quoteResponse .result')
|
####### Functions ######
|
||||||
|
|
||||||
# Display stocks data
|
symbol_currency() {
|
||||||
|
case $currency in
|
||||||
|
EUR)
|
||||||
|
echo -n "€"
|
||||||
|
;;
|
||||||
|
USD)
|
||||||
|
echo -n "$"
|
||||||
|
;;
|
||||||
|
GBP)
|
||||||
|
echo -n "£"
|
||||||
|
;;
|
||||||
|
JPY)
|
||||||
|
echo -n "¥"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
t=0
|
# Check if number is positive (or 0) or negative
|
||||||
|
CheckSign() {
|
||||||
|
local n="$1" # Capture the number passed as a parameter.
|
||||||
|
|
||||||
echo -e "${bold}stocks.sh${reset}\n"
|
if [ $(echo "$n < 0" | bc -l) -eq 1 ] ; then
|
||||||
|
#printf "%+17.13f : %s\n" "$n" "negative"
|
||||||
|
p="-"
|
||||||
|
else
|
||||||
|
#printf "%+17.13f : %s\n" "$n" "positive or zero"
|
||||||
|
p="+"
|
||||||
|
fi
|
||||||
|
echo "$p"
|
||||||
|
}
|
||||||
|
|
||||||
while IFS= read -r obj; do
|
[ ! -d "$SESSION_DIR" ] && mkdir -m 700 "$SESSION_DIR"
|
||||||
marketState=$(query 'marketState')
|
|
||||||
symbol=$(query 'symbol')
|
|
||||||
|
|
||||||
preMarketChange=$(query 'preMarketChange')
|
|
||||||
postMarketChange=$(query 'postMarketChange')
|
|
||||||
|
|
||||||
longName=$(query 'longName')
|
preflight () {
|
||||||
if [ "$longName" == "null" ] && [ $symbol == "^FCHI" ]; then
|
curl --silent --output /dev/null --cookie-jar "$COOKIE_FILE" "https://finance.yahoo.com" \
|
||||||
longName="CAC 40"
|
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"
|
||||||
fi
|
}
|
||||||
|
|
||||||
if [ $t == "0" ]; then
|
fetch_chart () {
|
||||||
printf "${bold}%-10s | %-21s | %-7s | " "Symbole" "Entreprise" "Cours"
|
local symbol=$1
|
||||||
printf "%-6s | %-7s | %-7s | " "Diff" "%" "Veille"
|
local url="${API_ENDPOINT}${symbol}${API_SUFFIX}"
|
||||||
printf "%-7s | %-7s | %-8s | " "+ Haut" "+ Bas" "Volume"
|
curl --silent -b "$COOKIE_FILE" "$url"
|
||||||
printf "%-9s | %-25s | %-18s | " "Ouverture" "Heure" "52 semaines"
|
}
|
||||||
printf "%-7s | %-9s | %-9s | %-6s${reset}\n" "Qté" "Valoris." "+/- value" "Perf."
|
|
||||||
fi
|
|
||||||
t=1
|
|
||||||
|
|
||||||
if [ $marketState == "PRE" ] && [ $preMarketChange != "0" ] && [ $preMarketChange != "null" ]; then
|
[ ! -f "$COOKIE_FILE" ] && preflight
|
||||||
nonRegularMarketSign='*'
|
|
||||||
price=$(query 'preMarketPrice')
|
|
||||||
diff=$preMarketChange
|
####### Start Display ######
|
||||||
percent=$(query 'preMarketChangePercent')
|
|
||||||
elif [ $marketState != "REGULAR" ] && [ $postMarketChange != "0" ] && [ $postMarketChange != "null" ]; then
|
echo -e "${COLOR_GREEN_BOLD}Bash Stocks${COLOR_RESET} $VERSION"
|
||||||
nonRegularMarketSign='*'
|
echo -e "Using Yahoo Finance API ($API_ENDPOINT)\n"
|
||||||
price=$(query 'postMarketPrice')
|
|
||||||
diff=$postMarketChange
|
|
||||||
percent=$(query 'postMarketChangePercent')
|
### Read quotes from arguments or from~/.stocks.yaml config file
|
||||||
|
SYMBOLS=()
|
||||||
|
|
||||||
|
# from arguments
|
||||||
|
if [ -n "$ScriptArgs" ]; then
|
||||||
|
|
||||||
|
REGEXP='^[a-zA-Z0-9.,_ ]+$'
|
||||||
|
q="$@"
|
||||||
|
if [[ "$q" =~ $REGEXP ]]; then
|
||||||
|
q=${q//,/\ }
|
||||||
|
q=${q//_/\ }
|
||||||
|
|
||||||
|
SYMBOLS+=($q)
|
||||||
else
|
else
|
||||||
nonRegularMarketSign=''
|
Help
|
||||||
price=$(query 'regularMarketPrice')
|
exit 1
|
||||||
diff=$(query 'regularMarketChange')
|
|
||||||
percent=$(query 'regularMarketChangePercent')
|
|
||||||
previous=$(query 'regularMarketPreviousClose')
|
|
||||||
volume=$(query 'regularMarketVolume')
|
|
||||||
haut=$(query 'regularMarketDayHigh')
|
|
||||||
bas=$(query 'regularMarketDayLow')
|
|
||||||
ouverture=$(query 'regularMarketOpen')
|
|
||||||
ts=$(query 'regularMarketTime')
|
|
||||||
heure=$(LC_ALL=fr_FR.UTF-8 date -d @$ts +"%c" 2>/dev/null || LC_ALL=fr_FR.UTF-8 date -r $ts +"%c")
|
|
||||||
ftweeks=$(query 'fiftyTwoWeekRange')
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Stocks owned
|
: <<'END_COMMENT'
|
||||||
#z=$(jq -c '.[] | select(.symbol == "'${symbol}'")' <<<$b)
|
|
||||||
z=$(yq '.[] | select(.symbol == "'${symbol}'")' <<< "$b")
|
|
||||||
|
|
||||||
if [ -n "$z" ]; then
|
# Check if quotes passed as argument really exist
|
||||||
#echo "$z"
|
|
||||||
#quantity=$(jq -c '.[] | select(.symbol == "'${symbol}'") | .quantity' <<< $b)
|
|
||||||
#quantity=$(jq -c '.quantity' <<<$z)
|
|
||||||
#unit_cost=$(jq -c '.unit_cost' <<<$z)
|
|
||||||
quantity=$(yq '.quantity' <<<$z)
|
|
||||||
unit_cost=$(yq '.unit_cost' <<<$z)
|
|
||||||
purchase=$(echo "$quantity * $unit_cost" | bc -l)
|
|
||||||
valuations=$(echo "$quantity * $price" | bc -l)
|
|
||||||
profit=$(echo "$valuations - $purchase" | bc -l)
|
|
||||||
performance=$(echo "($valuations / $purchase - 1) * 100" | bc -l)
|
|
||||||
performance=$(round $performance 2)
|
|
||||||
|
|
||||||
#valuation=$(($quantity * $price))
|
for val in ${!SYMBOLS[@]}
|
||||||
#profit=$((valuations-purchase))
|
do
|
||||||
#profit=$(($valuations-$purchase))
|
k="${SYMBOLS[$val]}"
|
||||||
#profit=$(($purchase-$valuations))
|
|
||||||
#((profit = valuations - purchase))
|
|
||||||
|
|
||||||
#echo "Qte: $quantity - PM: $unit_cost - Achat: $purchase - Valorisation: $valuations"
|
#echo $val # index
|
||||||
#echo "+-value: $profit - Perf: $performance%"
|
#echo $k # value
|
||||||
fi
|
|
||||||
|
if [[ ! "$list_coins" == *"$k"* ]]; then
|
||||||
|
echo -e "${COLOR_RED}$k is not a crypto. Remove it !${COLOR_RESET}"
|
||||||
|
unset SYMBOLS[$val]
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Recreate the array, because the gaps have to disappear
|
||||||
|
SYMBOLS=("${SYMBOLS[@]}")
|
||||||
|
END_COMMENT
|
||||||
|
|
||||||
|
echo -e "${COLOR_GREEN}Found ${#SYMBOLS[@]} stocks to display: ${SYMBOLS[@]} ...${COLOR_RESET}"
|
||||||
|
|
||||||
|
# from ~/.stocks.yaml config file
|
||||||
|
else
|
||||||
|
|
||||||
|
if [ -f "$stocks_list" ]; then
|
||||||
|
sl=$(cat $stocks_list)
|
||||||
|
[ $? -eq 0 ] && echo -e "${COLOR_GREEN}Reading $stocks_list ...${COLOR_RESET}" || echo -e "${COLOR_RED}Error while reading $stocks_list ...${COLOR_RESET}"
|
||||||
|
|
||||||
|
a=$(yq '.watchlist[]' <<< $sl)
|
||||||
|
SYMBOLS+=(${a})
|
||||||
|
[ $? -eq 0 ] && echo -e "${COLOR_GREEN}Found ${#SYMBOLS[@]} stocks to display: ${SYMBOLS[@]} ...${COLOR_RESET}" || echo -e "${COLOR_RED}No coins to display...${COLOR_RESET}"
|
||||||
|
|
||||||
|
b=$(yq '.lot' <<< $sl)
|
||||||
|
u=$((yq '.lots[] | select(.quantity != 0) | .symbol' | tr '\n' ' ') <<< $sl)
|
||||||
|
purchased=(${u})
|
||||||
|
[ $? -eq 0 ] && echo -e "${COLOR_GREEN}Found ${#purchased[@]} quotes purchased: ${purchased[@]} ...${COLOR_RESET}" || echo -e "${COLOR_RED}Fail to load quotes list purchased...${COLOR_COLOR_RESET}"
|
||||||
|
|
||||||
|
# Check that purchased's stocks are in display list
|
||||||
|
for val in ${!purchased[@]}
|
||||||
|
do
|
||||||
|
x="${purchased[$val]}"
|
||||||
|
if [[ " ${SYMBOLS[*]} " != *"$x"* ]]; then
|
||||||
|
SYMBOLS+=(${x})
|
||||||
|
echo -e "${COLOR_RED}$x is not in stocks's list to display. We add it !${COLOR_GREEN}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ $? -eq 0 ] && echo -e "${COLOR_GREEN}Found ${#SYMBOLS[@]} stocks to display: ${SYMBOLS[@]} ...${COLOR_RESET}" || echo -e "${COLOR_RED}No coins to display...${COLOR_RESET}"
|
||||||
|
|
||||||
# Lines colors: + green ; - red ; 0 no color
|
|
||||||
if [ "$diff" == "0" ] || [ "$diff" == "0.0" ]; then
|
|
||||||
color=
|
|
||||||
elif (echo "$diff" | grep -q ^-); then
|
|
||||||
color=$red
|
|
||||||
#cours_color="\033[3;31m"
|
|
||||||
cours_color="\033[1;37;1;41m"
|
|
||||||
else
|
else
|
||||||
color=$green
|
echo -e "${COLOR_RED}$stocks_list not present !${COLOR_RESET}"
|
||||||
#cours_color="\033[3;32m"
|
echo ""
|
||||||
cours_color="\033[1;37;1;42m"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Displaying
|
#echo "${SYMBOLS[@]}"
|
||||||
if [ "$price" != "null" ]; then
|
#echo "${purchased[@]}"
|
||||||
printf "${color}%-10s | %-21s | ${reset}${cours_color}%7.2f${reset}${color} | " $symbol "$longName" $price
|
|
||||||
printf "% 6.2f | % 6.2f%% | %7.2f | " $diff $percent $previous
|
: <<'END_COMMENT'
|
||||||
printf "%7.2f | %7.2f | %8d | " $haut $bas $volume
|
while IFS= read -r obj; do
|
||||||
printf "%9.2f | %25s | %18s | " $ouverture "$heure" "$ftweeks"
|
#echo "$obj"
|
||||||
if [ -n "$z" ]; then
|
stock=${obj:2}
|
||||||
printf "%6d | %9.2f | %9.2f | % 6.2f%%${reset}\n" $quantity $valuations $profit $performance
|
#echo "$stock"
|
||||||
else
|
SYMBOLS+=("$stock")
|
||||||
echo ""
|
done < <(echo "$a")
|
||||||
fi
|
[ $status -eq 0 ] && echo -e "${COLOR_GREEN}Found ${#SYMBOLS[@]} stocks to display: ${SYMBOLS[@]} ...${COLOR_RESET}" || echo -e "${COLOR_RED}No coins to display...${COLOR_RESET}"
|
||||||
|
END_COMMENT
|
||||||
|
if [ -z "$SYMBOLS" ]; then
|
||||||
|
echo "Usage: ./crypto.sh"
|
||||||
|
echo " - add quotes to ~/.stocks.yaml file"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
done < <(echo "$results" | jq -c '.[]')
|
fi
|
||||||
|
|
||||||
d=$(LC_ALL=fr_FR.UTF-8 TZ='Europe/Paris' date +"%c")
|
: <<'END_COMMENT'
|
||||||
echo -e "\n${reset}Dernière mise-à-jour: ${bold}$d${reset}"
|
### Parse options
|
||||||
|
|
||||||
|
while getopts "g" opt; do
|
||||||
|
case ${opt} in
|
||||||
|
h )
|
||||||
|
echo "Usage: ./ticker.sh [-g] AAPL GOOG ORA.PA"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND -1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
END_COMMENT
|
||||||
|
|
||||||
|
|
||||||
|
# volume %11s
|
||||||
|
echo
|
||||||
|
printf "%s%-22s %-8s %9s %8s %8s %9s %9s %11s %9s %9s %18s %18s %s \n" \
|
||||||
|
"${BOLD}" "ShortName" "Symbol" \
|
||||||
|
"Current" "Change" "Percent" \
|
||||||
|
"Day High" "Day Low" "Volume" \
|
||||||
|
"52w +" "52w -" "Last Date" "Timezone" \
|
||||||
|
"${COLOR_RESET}"
|
||||||
|
|
||||||
|
# Sort arrays (lists of quotes / purchased)
|
||||||
|
|
||||||
|
IFS=$'\n'
|
||||||
|
SYMBOLS=($(sort <<<"${SYMBOLS[*]}"))
|
||||||
|
purchased=($(sort <<<"${purchased[*]}"))
|
||||||
|
unset IFS
|
||||||
|
|
||||||
|
|
||||||
|
### Create JSON purchased quotes
|
||||||
|
|
||||||
|
# Create an initial block
|
||||||
|
jq -n '{"quotes":[]}' > "${json_file}"
|
||||||
|
ii=1
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize an array to hold background process IDs (avec les PID activés => affichage dans le désordre (au fil de l'eau))
|
||||||
|
pids=()
|
||||||
|
|
||||||
|
echo "quotes: ${#SYMBOLS[@]} - ${SYMBOLS[@]}"
|
||||||
|
echo "purchased: ${#purchased[@]} - ${purchased[@]}"
|
||||||
|
|
||||||
|
|
||||||
|
for symbol in "${SYMBOLS[@]}"; do
|
||||||
|
(
|
||||||
|
# Running in subshell
|
||||||
|
|
||||||
|
results=$(fetch_chart "$symbol")
|
||||||
|
|
||||||
|
regularMarketTime=$(echo "$results" | jq -r '.chart.result[0].meta.regularMarketTime')
|
||||||
|
#rdate -d @$regularMarketTime +"%c"
|
||||||
|
rmt=$(LC_ALL=fr_FR.UTF-8 date -d @$regularMarketTime +"%d/%m/%y %H:%M:%S" 2>/dev/null || LC_ALL=fr_FR.UTF-8 date -r $regularMarketTime +"%d/%m/%y %H:%M:%S")
|
||||||
|
|
||||||
|
exchangeTimezoneName=$(echo "$results" | jq -r '.chart.result[0].meta.exchangeTimezoneName')
|
||||||
|
fiftyTwoWeekHigh=$(echo "$results" | jq -r '.chart.result[0].meta.fiftyTwoWeekHigh')
|
||||||
|
fiftyTwoWeekLow=$(echo "$results" | jq -r '.chart.result[0].meta.fiftyTwoWeekLow')
|
||||||
|
regularMarketDayHigh=$(echo "$results" | jq -r '.chart.result[0].meta.regularMarketDayHigh')
|
||||||
|
regularMarketDayLow=$(echo "$results" | jq -r '.chart.result[0].meta.regularMarketDayLow')
|
||||||
|
regularMarketVolume=$(echo "$results" | jq -r '.chart.result[0].meta.regularMarketVolume')
|
||||||
|
longName=$(echo "$results" | jq -r '.chart.result[0].meta.longName')
|
||||||
|
shortName=$(echo "$results" | jq -r '.chart.result[0].meta.shortName')
|
||||||
|
|
||||||
|
currentPrice=$(echo "$results" | jq -r '.chart.result[0].meta.regularMarketPrice')
|
||||||
|
previousClose=$(echo "$results" | jq -r '.chart.result[0].meta.chartPreviousClose')
|
||||||
|
currency=$(echo "$results" | jq -r '.chart.result[0].meta.currency')
|
||||||
|
symb=$(symbol_currency $currency)
|
||||||
|
symbol=$(echo "$results" | jq -r '.chart.result[0].meta.symbol')
|
||||||
|
|
||||||
|
[ "$previousClose" = "null" ] && previousClose="1.0"
|
||||||
|
|
||||||
|
priceChange=$(awk -v currentPrice="$currentPrice" -v previousClose="$previousClose" 'BEGIN {printf "%.2f", currentPrice - previousClose}')
|
||||||
|
percentChange=$(awk -v currentPrice="$currentPrice" -v previousClose="$previousClose" 'BEGIN {printf "%.2f", ((currentPrice - previousClose) / previousClose) * 100}')
|
||||||
|
|
||||||
|
open=$(echo "$results" | jq -r '.chart.result[0].indicators.quote' | jq -r '.[].open[0]')
|
||||||
|
|
||||||
|
#firstTradeDate=$(echo "$results" | jq -r '.chart.result[0].meta.firstTradeDate')
|
||||||
|
#ftd==$(LC_ALL=fr_FR.UTF-8 date -d @$firstTradeDate +"%c" 2>/dev/null || LC_ALL=fr_FR.UTF-8 date -r $ts +"%c")
|
||||||
|
#volume=$(echo "$results" | jq -r '.chart.result[0].indicators.quote' | jq -r '.[].volume[0]')
|
||||||
|
#high=$(echo "$results" | jq -r '.chart.result[0].indicators.quote' | jq -r '.[].high[0]')
|
||||||
|
#close=$(echo "$results" | jq -r '.chart.result[0].indicators.quote' | jq -r '.[].close[0]')
|
||||||
|
|
||||||
|
if [[ " ${purchased[*]} " == *"$symbol"* ]]; then
|
||||||
|
|
||||||
|
|
||||||
|
# Create a temporary JSON file for purchased quotes because requests arrive as they come in (not in order)
|
||||||
|
# https://www.codegix.com/use-jq-to-create-a-dynamic-json-data-in-bash/
|
||||||
|
json_data=$(jq \
|
||||||
|
--arg symbol "$symbol" \
|
||||||
|
--arg price "$currentPrice" \
|
||||||
|
--arg volume "$regularMarketVolume" \
|
||||||
|
--arg last "$regularMarketTime" \
|
||||||
|
--arg symb "$symb" \
|
||||||
|
--arg percent "$percentChange" \
|
||||||
|
--argjson value "$ii" '.quotes += [{ "symbol": $symbol, "price": $price, "volume": $volume, "last": $last, "symb": $symb, "percent": $percent }]' "${json_file}")
|
||||||
|
|
||||||
|
echo "${json_data}" > "${json_file}"
|
||||||
|
|
||||||
|
((ii++))
|
||||||
|
|
||||||
|
: <<'END_COMMENT'
|
||||||
|
|
||||||
|
# Check quotes we have (from .stocks.yaml)
|
||||||
|
z=$(echo "$sl" | yq '.lots[] | select(.symbol == "'${symbol}'")')
|
||||||
|
q=$(echo "$z" | yq '.quantity')
|
||||||
|
uc=$(echo "$z" | yq '.unit_cost')
|
||||||
|
|
||||||
|
purchase_cost=$(echo "$q * $uc" | bc -l)
|
||||||
|
valuations=$(echo "$q * $currentPrice" | bc -l)
|
||||||
|
profit=$(echo "$valuations - $purchase_cost" | bc -l)
|
||||||
|
performance=$(echo "($valuations / $purchase_cost - 1) * 100" | bc -l)
|
||||||
|
#performance=$(round $performance 2)
|
||||||
|
|
||||||
|
echo "$q - $uc - $purchase_cost - $valuations - $profit - $performance"
|
||||||
|
END_COMMENT
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
COLOR_pri=$([ $(CheckSign "$priceChange") == "-" ] && echo ${COLOR_RED} || echo ${COLOR_GREEN})
|
||||||
|
COLOR_per=$([ $(CheckSign "$percentChange") == "-" ] && echo ${COLOR_RED} || echo ${COLOR_GREEN})
|
||||||
|
|
||||||
|
if [ -z "$NO_COLOR" ]; then
|
||||||
|
printf "%s%-22s %-8s %8.2f%s%s %s%7.2f%s%s %s%7.2f%%%s %s%8.2f%s %8.2f%s %11s %8.2f%s %8.2f%s %18s %18s %s\n" \
|
||||||
|
"${COLOR_YELLOW_BOLD}" "$shortName" "$symbol" \
|
||||||
|
"$currentPrice" "$symb" "${COLOR_RESET}" "${COLOR_pri}" "$priceChange" "$symb" "${COLOR_RESET}" "${COLOR_per}" "$percentChange" "${COLOR_RESET}" \
|
||||||
|
"${COLOR_YELLOW_BOLD}" "$regularMarketDayHigh" "$symb" "$regularMarketDayLow" "$symb" "$regularMarketVolume" \
|
||||||
|
"$fiftyTwoWeekHigh" "$symb" "$fiftyTwoWeekLow" "$symb" "$rmt" "$exchangeTimezoneName" "${COLOR_RESET}"\
|
||||||
|
|
||||||
|
else
|
||||||
|
printf "%-22s %-8s %8.2f%s %7.2f%s %7.2f%% %8.2f%s %8.2f%s %11s %8.2f%s %8.2f%s %18s %18s\n" \
|
||||||
|
"$shortName" "$symbol" \
|
||||||
|
"$currentPrice" "$symb" "$priceChange" "$symb" "$percentChange" \
|
||||||
|
"$regularMarketDayHigh" "$symb" "$regularMarketDayLow" "$symb" "$regularMarketVolume" \
|
||||||
|
"$fiftyTwoWeekHigh" "$symb" "$fiftyTwoWeekLow" "$symb" "$rmt" "$exchangeTimezoneName"
|
||||||
|
fi
|
||||||
|
|
||||||
|
) #&
|
||||||
|
|
||||||
|
# Stack PIDs
|
||||||
|
pids+=($!)
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
# Wait for all background processes to finish
|
||||||
|
for pid in "${pids[@]}"; do
|
||||||
|
wait "$pid"
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "quotes: ${#SYMBOLS[@]} - ${SYMBOLS[@]}"
|
||||||
|
echo "purchased: ${#purchased[@]} - ${purchased[@]}"
|
||||||
|
#cat $json_file
|
||||||
|
|
||||||
|
if [ ${#purchased[@]} -gt 0 ]; then
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo -e "${COLOR_GREEN}Displaying purchased quotes ...${COLOR_RESET}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
quotes="$(cat $json_file)"
|
||||||
|
counter=0
|
||||||
|
|
||||||
|
printf "%s%-8s %13s %10s %9s %11s %16s %13s %13s %13s %11s %18s %s\n" \
|
||||||
|
"${BOLD}" "Symbol" "Percent" "Current" "Quantity" "Unit cost" "Purchase cost" "Valuations" "Profit" "Performance" "Volume" "Last quote" "${COLOR_RESET}"
|
||||||
|
|
||||||
|
while [ "$counter" -lt "${#purchased[@]}" ]; do
|
||||||
|
|
||||||
|
purchase="${purchased[$counter]}"
|
||||||
|
|
||||||
|
s=$(echo "$quotes" | jq -r '.quotes | .[] | select(.symbol == "'${purchase}'") | (.symbol)') # Symbol
|
||||||
|
p=$(echo "$quotes" | jq -r '.quotes | .[] | select(.symbol == "'${purchase}'") | (.price)') # Price
|
||||||
|
v=$(echo "$quotes" | jq -r '.quotes | .[] | select(.symbol == "'${purchase}'") | (.volume)') # Volume
|
||||||
|
l=$(echo "$quotes" | jq -r '.quotes | .[] | select(.symbol == "'${purchase}'") | (.last)') # Last quote
|
||||||
|
rmt=$(LC_ALL=fr_FR.UTF-8 date -d @$l +"%d/%m/%y %H:%M:%S" 2>/dev/null || LC_ALL=fr_FR.UTF-8 date -r $l +"%d/%m/%y %H:%M:%S")
|
||||||
|
#echo $l # 1736526916
|
||||||
|
#rmt=$(LC_ALL=fr_FR.UTF-8 date -d "@$l" +"%c" 2>/dev/null || LC_ALL=fr_FR.UTF-8 date -r "$l" +"%c")
|
||||||
|
|
||||||
|
sy=$(echo "$quotes" | jq -r '.quotes | .[] | select(.symbol == "'${purchase}'") | (.symb)') # Symb (€/$/£)
|
||||||
|
pc=$(echo "$quotes" | jq -r '.quotes | .[] | select(.symbol == "'${purchase}'") | (.percent)') # Percent change
|
||||||
|
|
||||||
|
z=$(echo "$sl" | yq '.lots[] | select(.symbol == "'${purchase}'")')
|
||||||
|
q=$(echo "$z" | yq '.quantity')
|
||||||
|
uc=$(echo "$z" | yq '.unit_cost')
|
||||||
|
|
||||||
|
purchase_cost=$(echo "$q * $uc" | bc -l)
|
||||||
|
valuations=$(echo "$q * $p" | bc -l)
|
||||||
|
profit=$(echo "$valuations - $purchase_cost" | bc -l)
|
||||||
|
performance=$(echo "($valuations / $purchase_cost - 1) * 100" | bc -l)
|
||||||
|
#performance=$(round $performance 2)
|
||||||
|
|
||||||
|
COLOR_performance=$([ $(CheckSign "$performance") == "-" ] && echo ${COLOR_RED} || echo ${COLOR_GREEN})
|
||||||
|
|
||||||
|
#echo "$s - $p - $v - $rmt - $q - $uc - $purchase_cost - $valuations - $profit - $performance"
|
||||||
|
#echo "$purchase_cost - $valuations - $profit - $performance"
|
||||||
|
|
||||||
|
# symbol(s) percent (pc) price(p) quantity(q) unit_cost(uc) purchase_cost valuations profit performance volume(v) last_quote(l)
|
||||||
|
|
||||||
|
printf "%s%-8s %12.2f%% %9.2f%s %9d %10.2f%s %15.2f%s %12.2f%s %12.2f%s %12.2f%% %11d %18s %s\n" \
|
||||||
|
"${COLOR_performance}" "$s" "$pc" "$p" "$sy" "$q" "$uc" "$sy" "$purchase_cost" "$sy" "$valuations" "$sy" "$profit" "$sy" "$performance" "$v" "$rmt" "${COLOR_RESET}"
|
||||||
|
|
||||||
|
|
||||||
|
((++counter))
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n${ITALIC}Script with ${#SYMBOLS[@]} requests to Yahoo Finance API finished in $SECONDS seconds.${COLOR_RESET}"
|
||||||
|
|||||||
185
stocks_legacy.sh
Executable file
185
stocks_legacy.sh
Executable file
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
italic="\033[3m"
|
||||||
|
underline="\033[4m"
|
||||||
|
ita_under="\033[3;4m"
|
||||||
|
bgd="\033[1;4;31m"
|
||||||
|
red="\033[1;31m"
|
||||||
|
green="\033[1;32m"
|
||||||
|
bold="\033[1m"
|
||||||
|
box="\033[1;41m"
|
||||||
|
reset="\033[0m"
|
||||||
|
|
||||||
|
LANG=C
|
||||||
|
LC_NUMERIC=C
|
||||||
|
|
||||||
|
stocks_list=~/.stocks.yaml
|
||||||
|
|
||||||
|
query() {
|
||||||
|
echo "$obj" | jq -r ".$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
round() {
|
||||||
|
echo $(printf %.$2f $(echo "scale=$2;(((10^$2)*$1)+0.5)/(10^$2)" | bc))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test if jq & yq executables are in $PATH
|
||||||
|
|
||||||
|
if ! $(type jq >/dev/null 2>&1); then
|
||||||
|
echo "'jq' is not in the PATH. (See: https://stedolan.github.io/jq/)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $(type yq >/dev/null 2>&1); then
|
||||||
|
echo "'yq' is not in the PATH. (See: https://github.com/kislyuk/yq"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Read stocks from .stocks.yaml config file
|
||||||
|
|
||||||
|
if [ -f $stocks_list ]; then
|
||||||
|
#a=$(cat ~/.stocks.yaml | yq '.watchlist')
|
||||||
|
a=$(cat $stocks_list | yq '.watchlist')
|
||||||
|
b=$(cat $stocks_list | yq '.lots')
|
||||||
|
else
|
||||||
|
echo "$stocks_list not present !"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
while IFS= read -r obj; do
|
||||||
|
stock=${obj:2}
|
||||||
|
list+="$stock,"
|
||||||
|
done < <(echo "$a")
|
||||||
|
|
||||||
|
symbols=$(echo "$list" | sed 's/.$//')
|
||||||
|
|
||||||
|
# AC.PA ATO.PA AUB.PA CS.PA DG.PA ^FCHI VIRP.PA WLN.PA
|
||||||
|
|
||||||
|
#####
|
||||||
|
|
||||||
|
if [ -z "$symbols" ]; then
|
||||||
|
echo "Usage: ./stocks_legacy.sh"
|
||||||
|
echo " - add stocks to ~/.stocks.yaml file"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get stocks data from yahoo finance
|
||||||
|
|
||||||
|
API_ENDPOINT="https://query1.finance.yahoo.com/v7/finance/quote?lang=fr-FR®ion=FR&corsDomain=finance.yahoo.com"
|
||||||
|
|
||||||
|
results=$(curl --silent "$API_ENDPOINT&fields=$fields&symbols=$symbols" | jq '.quoteResponse .result')
|
||||||
|
|
||||||
|
# Display stocks data
|
||||||
|
|
||||||
|
t=0
|
||||||
|
|
||||||
|
echo -e "${bold}stocks_legacy.sh${reset}\n"
|
||||||
|
|
||||||
|
#query() {
|
||||||
|
# echo "$obj" | jq -r ".$1"
|
||||||
|
#}
|
||||||
|
|
||||||
|
while IFS= read -r obj; do
|
||||||
|
marketState=$(query 'marketState')
|
||||||
|
symbol=$(query 'symbol')
|
||||||
|
|
||||||
|
preMarketChange=$(query 'preMarketChange')
|
||||||
|
postMarketChange=$(query 'postMarketChange')
|
||||||
|
|
||||||
|
longName=$(query 'longName')
|
||||||
|
if [ "$longName" == "null" ] && [ $symbol == "^FCHI" ]; then
|
||||||
|
longName="CAC 40"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $t == "0" ]; then
|
||||||
|
printf "${bold}%-10s | %-21s | %-7s | " "Symbole" "Entreprise" "Cours"
|
||||||
|
printf "%-6s | %-7s | %-7s | " "Diff" "%" "Veille"
|
||||||
|
printf "%-7s | %-7s | %-8s | " "+ Haut" "+ Bas" "Volume"
|
||||||
|
printf "%-9s | %-25s | %-18s | " "Ouverture" "Heure" "52 semaines"
|
||||||
|
printf "%-7s | %-9s | %-9s | %-6s${reset}\n" "Qté" "Valoris." "+/- value" "Perf."
|
||||||
|
fi
|
||||||
|
t=1
|
||||||
|
|
||||||
|
if [ $marketState == "PRE" ] && [ $preMarketChange != "0" ] && [ $preMarketChange != "null" ]; then
|
||||||
|
nonRegularMarketSign='*'
|
||||||
|
price=$(query 'preMarketPrice')
|
||||||
|
diff=$preMarketChange
|
||||||
|
percent=$(query 'preMarketChangePercent')
|
||||||
|
elif [ $marketState != "REGULAR" ] && [ $postMarketChange != "0" ] && [ $postMarketChange != "null" ]; then
|
||||||
|
nonRegularMarketSign='*'
|
||||||
|
price=$(query 'postMarketPrice')
|
||||||
|
diff=$postMarketChange
|
||||||
|
percent=$(query 'postMarketChangePercent')
|
||||||
|
else
|
||||||
|
nonRegularMarketSign='' #nok
|
||||||
|
price=$(query 'regularMarketPrice')
|
||||||
|
diff=$(query 'regularMarketChange') #nok
|
||||||
|
percent=$(query 'regularMarketChangePercent') #nok
|
||||||
|
previous=$(query 'regularMarketPreviousClose') #nok
|
||||||
|
volume=$(query 'regularMarketVolume')
|
||||||
|
haut=$(query 'regularMarketDayHigh')
|
||||||
|
bas=$(query 'regularMarketDayLow')
|
||||||
|
ouverture=$(query 'regularMarketOpen') #nok
|
||||||
|
ts=$(query 'regularMarketTime')
|
||||||
|
heure=$(LC_ALL=fr_FR.UTF-8 date -d @$ts +"%c" 2>/dev/null || LC_ALL=fr_FR.UTF-8 date -r $ts +"%c")
|
||||||
|
ftweeks=$(query 'fiftyTwoWeekRange') #nok
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stocks owned
|
||||||
|
#z=$(jq -c '.[] | select(.symbol == "'${symbol}'")' <<<$b)
|
||||||
|
z=$(yq '.[] | select(.symbol == "'${symbol}'")' <<< "$b")
|
||||||
|
|
||||||
|
if [ -n "$z" ]; then
|
||||||
|
#echo "$z"
|
||||||
|
#quantity=$(jq -c '.[] | select(.symbol == "'${symbol}'") | .quantity' <<< $b)
|
||||||
|
#quantity=$(jq -c '.quantity' <<<$z)
|
||||||
|
#unit_cost=$(jq -c '.unit_cost' <<<$z)
|
||||||
|
quantity=$(yq '.quantity' <<<$z)
|
||||||
|
unit_cost=$(yq '.unit_cost' <<<$z)
|
||||||
|
purchase=$(echo "$quantity * $unit_cost" | bc -l)
|
||||||
|
valuations=$(echo "$quantity * $price" | bc -l)
|
||||||
|
profit=$(echo "$valuations - $purchase" | bc -l)
|
||||||
|
performance=$(echo "($valuations / $purchase - 1) * 100" | bc -l)
|
||||||
|
performance=$(round $performance 2)
|
||||||
|
|
||||||
|
#valuation=$(($quantity * $price))
|
||||||
|
#profit=$((valuations-purchase))
|
||||||
|
#profit=$(($valuations-$purchase))
|
||||||
|
#profit=$(($purchase-$valuations))
|
||||||
|
#((profit = valuations - purchase))
|
||||||
|
|
||||||
|
#echo "Qte: $quantity - PM: $unit_cost - Achat: $purchase - Valorisation: $valuations"
|
||||||
|
#echo "+-value: $profit - Perf: $performance%"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Lines colors: + green ; - red ; 0 no color
|
||||||
|
if [ "$diff" == "0" ] || [ "$diff" == "0.0" ]; then
|
||||||
|
color=
|
||||||
|
elif (echo "$diff" | grep -q ^-); then
|
||||||
|
color=$red
|
||||||
|
#cours_color="\033[3;31m"
|
||||||
|
cours_color="\033[1;37;1;41m"
|
||||||
|
else
|
||||||
|
color=$green
|
||||||
|
#cours_color="\033[3;32m"
|
||||||
|
cours_color="\033[1;37;1;42m"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Displaying
|
||||||
|
if [ "$price" != "null" ]; then
|
||||||
|
printf "${color}%-10s | %-21s | ${reset}${cours_color}%7.2f${reset}${color} | " $symbol "$longName" $price
|
||||||
|
printf "% 6.2f | % 6.2f%% | %7.2f | " $diff $percent $previous
|
||||||
|
printf "%7.2f | %7.2f | %8d | " $haut $bas $volume
|
||||||
|
printf "%9.2f | %25s | %18s | " $ouverture "$heure" "$ftweeks"
|
||||||
|
if [ -n "$z" ]; then
|
||||||
|
printf "%6d | %9.2f | %9.2f | % 6.2f%%${reset}\n" $quantity $valuations $profit $performance
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
done < <(echo "$results" | jq -c '.[]')
|
||||||
|
|
||||||
|
d=$(LC_ALL=fr_FR.UTF-8 TZ='Europe/Paris' date +"%c")
|
||||||
|
echo -e "\n${reset}Dernière mise-à-jour: ${bold}$d${reset}"
|
||||||
94
ticker.sh
94
ticker.sh
@@ -1,94 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
LANG=C
|
|
||||||
LC_NUMERIC=C
|
|
||||||
|
|
||||||
SYMBOLS=("$@")
|
|
||||||
|
|
||||||
if ! $(type jq > /dev/null 2>&1); then
|
|
||||||
echo "'jq' is not in the PATH. (See: https://stedolan.github.io/jq/)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$SYMBOLS" ]; then
|
|
||||||
echo "Usage: ./ticker.sh AAPL MSFT GOOG BTC-USD"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
FIELDS=(symbol marketState regularMarketPrice regularMarketChange regularMarketChangePercent regularMarketVolume regularMarketPreviousClose \
|
|
||||||
preMarketPrice preMarketChange preMarketChangePercent postMarketPrice postMarketChange postMarketChangePercent \
|
|
||||||
shortName longName fullExchangeName)
|
|
||||||
#API_ENDPOINT="https://query1.finance.yahoo.com/v7/finance/quote?lang=en-US®ion=US&corsDomain=finance.yahoo.com"
|
|
||||||
API_ENDPOINT="https://query1.finance.yahoo.com/v7/finance/quote?lang=fr-FR®ion=FR&corsDomain=finance.yahoo.com"
|
|
||||||
|
|
||||||
if [ -z "$NO_COLOR" ]; then
|
|
||||||
: "${COLOR_BOLD:=\e[1;37m}"
|
|
||||||
: "${COLOR_GREEN:=\e[32m}"
|
|
||||||
: "${COLOR_RED:=\e[31m}"
|
|
||||||
: "${COLOR_RESET:=\e[00m}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
symbols=$(IFS=,; echo "${SYMBOLS[*]}")
|
|
||||||
echo "$symbols"
|
|
||||||
|
|
||||||
fields=$(IFS=,; echo "${FIELDS[*]}")
|
|
||||||
|
|
||||||
results=$(curl --silent "$API_ENDPOINT&fields=$fields&symbols=$symbols" | jq '.quoteResponse .result')
|
|
||||||
#echo "$results"
|
|
||||||
|
|
||||||
query () {
|
|
||||||
echo $results | jq -r ".[] | select(.symbol == \"$1\") | .$2"
|
|
||||||
}
|
|
||||||
|
|
||||||
for symbol in $(IFS=' '; echo "${SYMBOLS[*]}" | tr '[:lower:]' '[:upper:]'); do
|
|
||||||
marketState="$(query $symbol 'marketState')"
|
|
||||||
|
|
||||||
if [ -z $marketState ]; then
|
|
||||||
printf 'No results for symbol "%s"\n' $symbol
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
preMarketChange="$(query $symbol 'preMarketChange')"
|
|
||||||
postMarketChange="$(query $symbol 'postMarketChange')"
|
|
||||||
|
|
||||||
longName="$(query $symbol 'longName')"
|
|
||||||
#regularMarketPreviousClose="$(query $symbol 'regularMarketPreviousClose')"
|
|
||||||
|
|
||||||
if [ $marketState == "PRE" ] \
|
|
||||||
&& [ $preMarketChange != "0" ] \
|
|
||||||
&& [ $preMarketChange != "null" ]; then
|
|
||||||
nonRegularMarketSign='*'
|
|
||||||
price=$(query $symbol 'preMarketPrice')
|
|
||||||
diff=$preMarketChange
|
|
||||||
percent=$(query $symbol 'preMarketChangePercent')
|
|
||||||
elif [ $marketState != "REGULAR" ] \
|
|
||||||
&& [ $postMarketChange != "0" ] \
|
|
||||||
&& [ $postMarketChange != "null" ]; then
|
|
||||||
nonRegularMarketSign='*'
|
|
||||||
price=$(query $symbol 'postMarketPrice')
|
|
||||||
diff=$postMarketChange
|
|
||||||
percent=$(query $symbol 'postMarketChangePercent')
|
|
||||||
else
|
|
||||||
nonRegularMarketSign=''
|
|
||||||
price=$(query $symbol 'regularMarketPrice')
|
|
||||||
diff=$(query $symbol 'regularMarketChange')
|
|
||||||
percent=$(query $symbol 'regularMarketChangePercent')
|
|
||||||
previous=$(query $symbol 'regularMarketPreviousClose')
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$diff" == "0" ] || [ "$diff" == "0.0" ]; then
|
|
||||||
color=
|
|
||||||
elif ( echo "$diff" | grep -q ^- ); then
|
|
||||||
color=$COLOR_RED
|
|
||||||
else
|
|
||||||
color=$COLOR_GREEN
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$price" != "null" ]; then
|
|
||||||
#printf "%-10s$COLOR_BOLD%8.2f$COLOR_RESET" $symbol $price
|
|
||||||
printf "%-10s%-35s$COLOR_BOLD%8.2f$COLOR_RESET" $symbol "$longName" $price
|
|
||||||
printf "$color%10.2f%12s$COLOR_RESET%+10s" $diff $(printf "(%.2f%%)" $percent) $previous
|
|
||||||
printf " %s\n" "$nonRegularMarketSign"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
Reference in New Issue
Block a user