March 2008 Archives

Ripartire un importo su più periodi

| | Comments (0)

Se vi siete occupati di Controllo di Gestione, avrete sicuramente incontrato il problema della "competenza", e della necessità di ripartire dei valori riferiti ad un periodo, sui corrispondenti mesi.

Qualche esempio ?    il canone periodico di un affitto, un abbonamento, un contratto di assistenza.... il pagamento avviene ad una certa data, ma copre un periodo, ed in genere c'è il bisogno di suddividere il costo sui mesi.

La cosa può sembrare un tantino complicata se il perido è identificato da due date (inizio e fine) che con coincidono con l'inizio e la fine del mese.

Quella che propongo, è una soluzione basata sulla funzione while.

Supponiamo che i dati siano un budget; ogni riga è identificata da un Codice, un Periodo ed un Importo, del tipo:
 

Budget:
Load * inline [
BDGcodice, BDGinizio, BDGfine, BDGimporto
A, 15/01/2008, 02/02/2008, 100
B, 03/01/2008, 03/02/2008, 100
C, 15/09/2008, 02/02/2009, 100
];

 
Lo script per generare una tabella con l'importo (BDGimporto) suddiviso per mese è:
 
BudgetRipartito:

Load
 BDGcodice
,BDGinizioPeriodo
,BDGfinePeriodo
,BDGimporto * (BDGfinePeriodo - BDGinizioPeriodo + 1)

/ (BDGfine - BDGinizio + 1)

as BDGimportoPeriodo;
Load
 *
,if(iterNo()=1

,BDGinizio

,addMonths(makeDate(year(BDGinizio),month(BDGinizio)),iterNo()-1)

) as BDGinizioPeriodo
,if(iterNo()=BDGnumMesi

,BDGfine

,addMonths(makeDate(year(BDGinizio),month(BDGinizio)),iterNo())-1

) as BDGfinePeriodo
while iterNo() <= BDGnumMesi;
Load
 *
,BDGmeseFine - BDGmeseInizio + 1 as BDGnumMesi;
Load
 BDGimporto
,BDGcodice
,BDGinizio
,BDGfine
,year(BDGinizio)*12 + Month(BDGinizio) as BDGmeseInizio
,year(BDGfine)*12 + Month(BDGfine) as BDGmeseFine
resident Budget;


 

Qualche spiegazione potrebbe essere utile:

Beh, le load sono scritte in cascata: QlikView passa il risultato di quella più "bassa" a quella immediatamente superiore. Io trovo questa tecnica più facile da leggere rispetto alla "nidificazione" delle funzioni, ma forse è questione di gusti. Invece mi sembra una tecnica molto utile per "perdere" dei campi che all'inizio servono e poi non servono più... invece di crearli e poi farne la drop, con questa tecnica è sufficiente non citarli nelle load superiore, cioè quella che - finalmente - inserisce i dati nella tabella in memoria.

Poi forse avrete notato il mio vezzo di mettere la virgola all'inizio della riga successiva.. potrei tenervi ore sul significato della cosa, ma ve lo risparmio; prendetelo per quello che è.. un vezzo.

Finalmente arriviamo alla funzione WHILE; prima di tutto contiamo il numero di mesi che sono "toccati" dal periodo. A questo punto, se abbiamo in INPUT un record, in OUTPUT ne dovremo avere uno per ciascun mese "toccato".   La funzione WHILE permette di ripetere la scrittura del record più volte. Ovviamente bisogna "contare" a che punto siamo arrivati, e questo lo fa la funzione iterNo(), che appunto "conta" le ripetizioni fatte.

Il resto è semplice matematica con le date.... però funziona !

 

QlikView 8 ha la funzione age(), che calcola l'età avendo la data di nascita e la data alla quale calcolarla. QlikView 7 no.
Moltissime aziende usano ancora il 7, e la necessità di calcolare l'età è ricorrente. A volte ho visto adottare come soluzione il calcolo della differenza in giorni, che viene poi divisa per 365: è un modo che sinceramente ritengo troppo approssimativo.

Il metodo che propongo è: se, per l'anno corrente, il compleanno è già passato, allora l'età è pari all'anno corrente meno l'anno di nascita. Se, invece, il compleanno non è ancora passato, allora l'età è pari all'anno corrente meno l'anno di nascita, meno uno!
Praticamente, in una ipotetica load:

// soluzione A
load if(
	month(DATA_NASCITA) < month(today())
	or
	(
		month(DATA_NASCITA) = month(today())
		and
		day(DATA_NASCITA) <= day(today())
	)
	,
	year(today()) - year(DATA_NASCITA)
	,
	year(today()) - year(DATA_NASCITA) - 1
) as eta,
...;

Oppure, soluzione equivalente ma più interessante (si basa sul fatto che per QlikView false() è pari a -1 e true() è pari a 0):

// soluzione B
load year(today()) - year(DATA_NASCITA) + (
	month(DATA_NASCITA) > month(today())
	or
	(
		month(DATA_NASCITA) = month(today())
		and
		day(DATA_NASCITA) > day(today())
	)
) as eta,
...;

Ho fatto qualche prova sul mio portatile, caricando solo l'età da circa 10 milioni di righe: la funzione age() di QlikView 8 impiega 18 secondi, la soluzione A ne impiega 24, e la soluzione B ne impiega 22, il 10% in meno di A.
È stato divertente!

candele.png I grafici a Candele Giapponesi (candlestick) sono molto usati nell'Analisi Tecnica.
Sono un'ottima rappresentazione dell'andamento dei prezzi di un titolo di borsa, oppure di una valuta, o un bene di qualunque genere, in un dato periodo. Un normale line chart si limita a mostrare un punto per ogni giorno (d'ora in poi assumerò il giorno come unità base, ma si può generalizzare), dando una sola informazione (il prezzo medio per giorno, ad esempio) mentre un grafico a candele è molto più completo: ogni giorno è rappresentato da una candela, che può essere bianca o nera, ed ha uno stoppino sopra e sotto. Il corpo della candela indica la distanza fra il prezzo di apertura e di chiusura del giorno: se la candela è nera, ha chiuso in negativo e quindi il livello più alto del corpo della candela rappresenta il prezzo di apertura, ed il livello più basso il prezzo di chiusura; se invece ha chiuso in positivo il corpo della candela è bianco ed il prezzo maggiore è, ovviamente, quello di fine giornata.
Gli stoppini, invece, rappresentano il valore massimo e minimo che ha avuto il prezzo in quel giorno. Infatti, tipicamente i prezzi oscillano molto fra l'apertura e la chiusura, e quest'informazione è preziosa per immaginare il comportamento del giorno successivo.

Le Candele Giapponesi devono il loro nome alla forma che hanno, e perché sono state inventate nel Giappone del XII secolo: già a quei tempi c'era chi speculava sul prezzo del riso, in mercati simili alle odierne borse.
Sono passati 800 anni ma questa rappresentazione grafica resta fra le più complete, solo che viene generata da applicazioni software, e si può fare anche con QlikView.
Nell'esempio riporto appunto un grafico che ho creato con QlikView: l'andamento dei prezzi delle azioni di Tiscali S.p.A. a Gennaio e Febbraio 2008, a cui ho aggiunto anche il volume scambiato.

Per farle è necessario impostare il grafico come Combo Chart e selezionare Box Plot come rappresentazione per l'espressione dalle proprietà del grafico: cliccando sul + accanto all'espressione, si potranno inserire Top, Bottom, Upper Whisker, Lower Whisker: rispettivamente il valore massimo fra quello di apertura e di chiusura, il valore minimo fra apertura e chiusura, il massimo della giornata ed il minimo.
Importante notare che raramente il valore di apertura è lo stesso di chiusura del giorno precedente, infatti fenomeni che avvengono mentre la borsa è chiusa condizionano l'apertura successiva (ad esempio comunicati stampa, ma anche semplicemente decisioni prese dagli azionisti).

Potete caricare i dati che ho usato per disegnare quel grafico col seguente codice:

SET ThousandSep=',';
SET DecimalSep='.';
load
	Date,
	Open,
	High,
	Low,
	Close,
	Volume,
	[Adj Close]
from [http://ichart.finance.yahoo.com/table.csv?s=TIS.MI]
(ansi, txt, delimiter is ',', embedded labels, msq);

La tabella caricata dal sito di Yahoo è già denormalizzata, ma in caso si avesse una tabella normalizzata (quindi con le coppie data e ora / valore), si può usare come valore di apertura l'espressione firstsortedvalue(prezzo, ora) e per la chiusura firstsortedvalue(prezzo, -ora), con una dimensione che indica il giorno.

Con le Candele Giapponesi sono identificabili delle figure ricorrenti, dette pattern, nel grafico che vi porto come esempio è interessante notare l'Hanging Man di Venerdì 8 Febbraio, confermato dalla candela nera del Lunedì successivo.
Infatti, la candela di quel Venerdì seppur bianca ha uno stoppino inferiore molto lungo, indice che qualche forza tirava i prezzi verso il basso (anche se han vinto i tori): quello che con un semplice line chart sarebbe sembrato erroneamente un'impennata dei prezzi, quindi un segnale di acquisto, si rivela correttamente come un campanello d'allarme con la rappresentazione candlestick, grazie al suo stoppino.
Potente, vero?

compressione.png QlikView permette di specificare una compressione per i documenti, in modo da occupare meno spazio su disco.
Con la compressione Alta, il .qvw occuperà poco spazio. Con Nessuna, occuperà tipicamente due o tre volte più spazio.

Occhio però: se il documento è molto molto grosso, cioè proprio quando la compressione farebbe comodo, il tempo di apertura di un documento compresso è sensibilmente maggiore del tempo di apertura di un documento non compresso. Può essere un'arma a doppio taglio.

Da un cliente ho dovuto disabilitare la compressione, perché l'apertura del documento da parte di QlikView Server impiegava minuti; senza compressione impiega 20 secondi, ma occupa 1,2 GB di spazio su disco invece di 345 MB.
Pazienza.

Novità! Se vuoi essere contattato da un consulente Querit lascia nome e numero e Ti telefoneremo:





Pages