Pagina 1 di 1

[Risolto][Bash] Problema con parametri da riga di comando

MessaggioInviato: sabato 19 gennaio 2019, 18:09
da Vincenzo1968
Ciao a tutti,

Non m'intendo molto di bash, programmo in C.
Ho trovato in rete questo script che serve a prelevare le serie storiche dei prezzi sui mercati finanziari.
Lo script prende tre parametri da riga di comando. Il primo è obbligatorio, ed è il simbolo dello strumento finanziario(per esempio, "^GSPC" è il simbolo dell'indice "Standard & Poor's 500").
Gli altri due parametri, non obbligatori, sono la data di inizio e quella di fine.

Ora, se io specifico tutt'e tre i parametri, lo script funziona perfettamente.
Le date vanno specificate nel formato mese/giorno/anno.
Per esempio, per prendere le serie storiche dello S&P 500 dal 31 dicembre 2018 al 19 gennaio 2019:
[vincenzo]$ ./get-yahoo-quotes-new.sh ^GSPC 12/31/2018 1/19/2019
Downloading quotes for ^GSPC
https://finance.yahoo.com/quote/^GSPC/?p=^GSPC
VrZprdgL72R
CRUMB: VrZprdgL72R
https://query1.finance.yahoo.com/v7/finance/download/^GSPC?period1=1546210800&period2=1547852400&interval=1d&events=history
URL: https://query1.finance.yahoo.com/v7/finance/download/^GSPC?period1=1546210800&period2=1547852400&interval=1d&events=history&crumb=VrZprdgL72R
Data dowmloaded to ^GSPC.csv


Se invece ometto le due date, specificando soltanto il simbolo(in questo modo dovrebbe prendermi le serie storiche dalla data più lontana a oggi), mi dà questo errore:
[vincenzo]$ ./get-yahoo-quotes-new.sh ^GSPC
Downloading quotes for ^GSPC
date: data "-2177452800" non valida
date: data "1547913616" non valida


Questo è lo script:
Codice: Seleziona tutto
## 06-03-2017 : Created script
##
## ----------------------------------------------------------------------------------------------------

SYMBOL=$1
if [[ -z $SYMBOL ]]; then
  echo "Please enter a SYMBOL as the first parameter to this script"
  exit
fi
echo "Downloading quotes for $SYMBOL"

function log () {
  # To remove logging comment echo statement and uncoment the :
  echo $1
  # :
}

# Period values are 'Seconds since 1970-01-01 00:00:00 UTC'. Also known as Unix time or epoch time.
# Let's just assume we want it all and ask for a date range that starts at 1/1/1970.
# NOTE: This doesn't work for old synbols like IBM which has Yahoo has back to 1962
#START_DATE=0
# 1 gennaio 1901 = in Unix time: -2177452800
#START_DATE=-2177452800
#END_DATE=$(date +%s)

startDate=$2
if [[ -z $startDate ]]; then
  startDate=-2177452800
fi

endDate=$3
if [[ -z $endDate ]]; then
  endDate=$(date +%s)
fi

START_DATE=$(date -d "$startDate" '+%s')
END_DATE=$(date -d "$endDate" '+%s')


# Store the cookie in a temp file
cookieJar=$(mktemp)

# Get the crumb value
function getCrumb () {
  # Sometimes the value has an octal character
  # echo will convert it
  # https://stackoverflow.com/a/28328480

  # curl the url then replace the } characters with line feeds. This takes the large json one line and turns it into about 3000 lines
  # grep for the CrumbStore line
  # then copy out the value
  # lastly, remove any quotes
  echo -en "$(curl -s --cookie-jar $cookieJar $1)" | tr "}" "\n" | grep CrumbStore | cut -d':' -f 3 | sed 's+"++g'
}

# TODO If crumb is blank then we probably don't have a valid symbol
URL="https://finance.yahoo.com/quote/$SYMBOL/?p=$SYMBOL"
log $URL
crumb=$(getCrumb $URL)
log $crumb
log "CRUMB: $crumb"
if [[ -z $crumb ]]; then
  echo "Error finding a valid crumb value"
  exit
fi


# Build url with SYMBOL, START_DATE, END_DATE
BASE_URL="https://query1.finance.yahoo.com/v7/finance/download/$SYMBOL?period1=$START_DATE&period2=$END_DATE&interval=1d&events=history"
log $BASE_URL

# Add the crumb value
URL="$BASE_URL&crumb=$crumb"
log "URL: $URL"

# Download to
curl -s --cookie $cookieJar  $URL > $SYMBOL.csv

echo "Data dowmloaded to $SYMBOL.csv"

Re: [Bash] Problema con parametri da riga di comando

MessaggioInviato: sabato 19 gennaio 2019, 22:06
da rai
Ciao,
avrai capito che è un errore col formato delle stringhe che il comando date deve interpretare coma data
Ho fatto delle modifiche in tal senso e in questo modo mi crea un file.csv che parte dal 1950
Guarda se è il risultato che ti aspetti

Codice: Seleziona tutto
#!/bin/bash

## 06-03-2017 : Created script
##
## ----------------------------------------------------------------------------------------------------

SYMBOL=$1
if [[ -z $SYMBOL ]]; then
  echo "Please enter a SYMBOL as the first parameter to this script"
  exit
fi
echo "Downloading quotes for $SYMBOL"

function log () {
  # To remove logging comment echo statement and uncoment the :
  echo $1
  # :
}

# Period values are 'Seconds since 1970-01-01 00:00:00 UTC'. Also known as Unix time or epoch time.
# Let's just assume we want it all and ask for a date range that starts at 1/1/1970.
# NOTE: This doesn't work for old synbols like IBM which has Yahoo has back to 1962
#START_DATE=0
# 1 gennaio 1901 = in Unix time: -2177452800
#START_DATE=-2177452800
#END_DATE=$(date +%s)

startDate=$2
if [[ -z $startDate ]]; then
  startDate="01/01/1901"
fi

endDate=$3
if [[ -z $endDate ]]; then
  endDate=$(date '+%m/%d/%Y')
fi

START_DATE=$(date -d "$startDate" '+%s')
END_DATE=$(date -d "$endDate" '+%s')


# Store the cookie in a temp file
cookieJar=$(mktemp)

# Get the crumb value
function getCrumb () {
  # Sometimes the value has an octal character
  # echo will convert it
  # https://stackoverflow.com/a/28328480

  # curl the url then replace the } characters with line feeds. This takes the large json one line and turns it into about 3000 lines
  # grep for the CrumbStore line
  # then copy out the value
  # lastly, remove any quotes
  echo -en "$(curl -s --cookie-jar $cookieJar $1)" | tr "}" "\n" | grep CrumbStore | cut -d':' -f 3 | sed 's+"++g'
}

# TODO If crumb is blank then we probably don't have a valid symbol
URL="https://finance.yahoo.com/quote/$SYMBOL/?p=$SYMBOL"
log $URL
crumb=$(getCrumb $URL)
log $crumb
log "CRUMB: $crumb"
if [[ -z $crumb ]]; then
  echo "Error finding a valid crumb value"
  exit
fi


# Build url with SYMBOL, START_DATE, END_DATE
BASE_URL="https://query1.finance.yahoo.com/v7/finance/download/$SYMBOL?period1=$START_DATE&period2=$END_DATE&interval=1d&events=history"
log $BASE_URL

# Add the crumb value
URL="$BASE_URL&crumb=$crumb"
log "URL: $URL"

# Download to
curl -s --cookie $cookieJar  $URL > $SYMBOL.csv

echo "Data dowmloaded to $SYMBOL.csv"


EDIT
nota che non ho toccato le righe di commento, non mi sono nemmeno messo a cercare di capirle

Re: [Bash] Problema con parametri da riga di comando

MessaggioInviato: sabato 19 gennaio 2019, 23:05
da UbuNuovo
A me pare sbagliata la logica, non ho guardato tutto con attenzione ma l'assegnazione delle date dovrebbe essere fatta così:
Codice: Seleziona tutto
#!/bin/bash

## 06-03-2017 : Created script
##
## ----------------------------------------------------------------------------------------------------

SYMBOL=$1
if [[ -z $SYMBOL ]]; then
  echo "Please enter a SYMBOL as the first parameter to this script"
  exit
fi
echo "Downloading quotes for $SYMBOL"

function log () {
  # To remove logging comment echo statement and uncoment the :
  echo $1
  # :
}

# Period values are 'Seconds since 1970-01-01 00:00:00 UTC'. Also known as Unix time or epoch time.
# Let's just assume we want it all and ask for a date range that starts at 1/1/1970.
# NOTE: This doesn't work for old synbols like IBM which has Yahoo has back to 1962
#START_DATE=0
# 1 gennaio 1901 = in Unix time: -2177452800
#START_DATE=-2177452800
#END_DATE=$(date +%s)

startDate=$2
if [[ -z $startDate ]]; then
   START_DATE=-2177452800
   else
   START_DATE=$(date -d "$startDate" '+%s')
fi

endDate=$3
if [[ -z $endDate ]]; then
   END_DATE=$(date +%s)
   else
      END_DATE=$(date -d "$endDate" '+%s')
fi

# Store the cookie in a temp file
cookieJar=$(mktemp)

# Get the crumb value
function getCrumb () {
  # Sometimes the value has an octal character
  # echo will convert it
  # https://stackoverflow.com/a/28328480

  # curl the url then replace the } characters with line feeds. This takes the large json one line and turns it into about 3000 lines
  # grep for the CrumbStore line
  # then copy out the value
  # lastly, remove any quotes
  echo -en "$(curl -s --cookie-jar $cookieJar $1)" | tr "}" "\n" | grep CrumbStore | cut -d':' -f 3 | sed 's+"++g'
}

# TODO If crumb is blank then we probably don't have a valid symbol
URL="https://finance.yahoo.com/quote/$SYMBOL/?p=$SYMBOL"
log $URL
crumb=$(getCrumb $URL)
log $crumb
log "CRUMB: $crumb"
if [[ -z $crumb ]]; then
  echo "Error finding a valid crumb value"
  exit
fi


# Build url with SYMBOL, START_DATE, END_DATE
BASE_URL="https://query1.finance.yahoo.com/v7/finance/download/$SYMBOL?period1=$START_DATE&period2=$END_DATE&interval=1d&events=history"
log $BASE_URL

# Add the crumb value
URL="$BASE_URL&crumb=$crumb"
log "URL: $URL"

# Download to
curl -s --cookie $cookieJar  $URL > $SYMBOL.csv

echo "Data dowmloaded to $SYMBOL.csv"


edit: #Rai non ho visto le tue modifiche ora guardo.

riedit: Sì, hai cambiato il formato della data.

Re: [Bash] Problema con parametri da riga di comando

MessaggioInviato: domenica 20 gennaio 2019, 14:34
da Vincenzo1968
rai e UbuNuovo, i vostri script funzionano a meraviglia.
Mi avete salvato la vita, grazie :birra:

rai: Sì, i dati partono dal 1950 perché è da quell'anno che sono disponibili su Yahoo finance per lo S&P 500.

Re: [Risolto][Bash] Problema con parametri da riga di comand

MessaggioInviato: domenica 20 gennaio 2019, 15:01
da UbuNuovo
In caso di assenza dei parametri con le date veniva richiesto di convertire in timestamp un dato che era già in formato timestamp; per questo si verificava l'errore.
Per risolvere o si modifica il formato data di imput predefinito, in modo che sia possibile convertirlo in timestamp (script Rai)
oppure Si cambia l'assegnazione delle date nella parte di verifica dei parametri (Script mio).
I metodi sono equivalenti, nel caso di cambio formato semmai aggiornare la data nel commento.
Ciaux

Re: [Risolto][Bash] Problema con parametri da riga di comand

MessaggioInviato: domenica 20 gennaio 2019, 16:07
da Vincenzo1968
UbuNuovo Immagine ha scritto:In caso di assenza dei parametri con le date veniva richiesto di convertire in timestamp un dato che era già in formato timestamp; per questo si verificava l'errore.
Per risolvere o si modifica il formato data di imput predefinito, in modo che sia possibile convertirlo in timestamp (script Rai)
oppure Si cambia l'assegnazione delle date nella parte di verifica dei parametri (Script mio).
I metodi sono equivalenti, nel caso di cambio formato semmai aggiornare la data nel commento.
Ciaux


Ciao UbuNuovo,
grazie mille.