accept --cpi=FILE --cpiy=YEAR to translate money to target year
cicd / ci (push) Successful in 1m30s
Details
cicd / ci (push) Successful in 1m30s
Details
parent
0d91cd63db
commit
2f8dba4e23
|
|
@ -1,9 +1,11 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Files FileList
|
Files FileList
|
||||||
BPI string
|
BPI string
|
||||||
Query struct {
|
CPI string
|
||||||
|
CPIYear int
|
||||||
|
Query struct {
|
||||||
Period Period
|
Period Period
|
||||||
Sort string
|
Sort string
|
||||||
NoRounding bool
|
NoRounding bool
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ func Main() {
|
||||||
fs.BoolVar(&config.Query.USDOnly, "usd", false, "filter to usd")
|
fs.BoolVar(&config.Query.USDOnly, "usd", false, "filter to usd")
|
||||||
fs.BoolVar(&config.Query.NoExchanging, "no-exchanging", true, "omit currency exchanges")
|
fs.BoolVar(&config.Query.NoExchanging, "no-exchanging", true, "omit currency exchanges")
|
||||||
fs.StringVar(&config.BPI, "bpi", "", "path to bpi")
|
fs.StringVar(&config.BPI, "bpi", "", "path to bpi")
|
||||||
|
fs.StringVar(&config.CPI, "cpi", "", "path to cpi")
|
||||||
|
fs.IntVar(&config.CPIYear, "cpiy", 0, "use cpi to convert usd to this year's value")
|
||||||
if err := fs.Parse(os.Args[1:]); err != nil {
|
if err := fs.Parse(os.Args[1:]); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -89,6 +91,23 @@ func Main() {
|
||||||
bpis = b
|
bpis = b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpiNormalizer := ana.NewNormalizer()
|
||||||
|
if config.CPI != "" && config.CPIYear > 0 {
|
||||||
|
c, err := ledger.NewBPIs(config.CPI)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
cpi := c["CPI"]
|
||||||
|
cpiy := cpi.Lookup(fmt.Sprintf("%d-06-01", config.CPIYear))
|
||||||
|
if cpiy == nil {
|
||||||
|
panic(fmt.Errorf("no cpi for year %d", config.CPIYear))
|
||||||
|
}
|
||||||
|
|
||||||
|
for date, value := range cpi {
|
||||||
|
cpiNormalizer = cpiNormalizer.With(".*", date, value/(*cpiy))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if config.Query.Normalize {
|
if config.Query.Normalize {
|
||||||
deltas = ana.NewDefaultNormalizer().Normalize(deltas)
|
deltas = ana.NewDefaultNormalizer().Normalize(deltas)
|
||||||
}
|
}
|
||||||
|
|
@ -113,13 +132,14 @@ func Main() {
|
||||||
WithBPIs(bpis).
|
WithBPIs(bpis).
|
||||||
KindaLike(q).
|
KindaLike(q).
|
||||||
KindaGroup(group).
|
KindaGroup(group).
|
||||||
Nonzero()
|
Nonzero().
|
||||||
|
Normalize(cpiNormalizer, "9")
|
||||||
FPrintBalances(w, "", balances, nil, config.Query.USDOnly, config.Query.Normalize, time.Now().Format("2006-01-02"), false, maxAccW)
|
FPrintBalances(w, "", balances, nil, config.Query.USDOnly, config.Query.Normalize, time.Now().Format("2006-01-02"), false, maxAccW)
|
||||||
case "reg":
|
case "reg":
|
||||||
transactions := deltas.Transactions()
|
transactions := deltas.Transactions()
|
||||||
cumulative := make(ledger.Balances)
|
cumulative := make(ledger.Balances)
|
||||||
for _, transaction := range transactions {
|
for _, transaction := range transactions {
|
||||||
balances := ledger.Deltas(transaction).Like(q).Group(group).Balances().WithBPIsAt(bpis, transaction[0].Date).Nonzero()
|
balances := ledger.Deltas(transaction).Like(q).Group(group).Balances().WithBPIsAt(bpis, transaction[0].Date).Nonzero().Normalize(cpiNormalizer, transaction[0].Date)
|
||||||
shouldPrint := false
|
shouldPrint := false
|
||||||
shouldPrint = shouldPrint || len(balances) > 2
|
shouldPrint = shouldPrint || len(balances) > 2
|
||||||
if config.Query.NoExchanging {
|
if config.Query.NoExchanging {
|
||||||
|
|
@ -220,7 +240,7 @@ func FPrintBalances(w io.Writer, linePrefix string, balances, cumulatives ledger
|
||||||
if !normalized {
|
if !normalized {
|
||||||
fmt.Fprintf(w, format, printableKey, printableCurrency, balances[key][currency], printableCurrency, cumulative)
|
fmt.Fprintf(w, format, printableKey, printableCurrency, balances[key][currency], printableCurrency, cumulative)
|
||||||
} else {
|
} else {
|
||||||
factor := normalizer.NormalizeFactor(ledger.Delta{Name: key, Date: date})
|
factor := normalizer.NormalizeFactor(key, date)
|
||||||
trailingMax := maxes[currency] - math.Abs(balances[key][currency])
|
trailingMax := maxes[currency] - math.Abs(balances[key][currency])
|
||||||
fmt.Fprintf(w, format, printableKey, printableCurrency, balances[key][currency], printableCurrency, cumulative, cumulative*factor, factor, printableCurrency, factor*trailingMax)
|
fmt.Fprintf(w, format, printableKey, printableCurrency, balances[key][currency], printableCurrency, cumulative, cumulative*factor, factor, printableCurrency, factor*trailingMax)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ func (router Router) APITransactions(w http.ResponseWriter, r *http.Request) {
|
||||||
v := normalized[k]
|
v := normalized[k]
|
||||||
if v := math.Abs(v["$"]); v < biggest {
|
if v := math.Abs(v["$"]); v < biggest {
|
||||||
normalizedDelta := biggest - v
|
normalizedDelta := biggest - v
|
||||||
normalizedFactor := normalizer.NormalizeFactor(ledger.Delta{Name: k, Date: time.Now().Format("2006-01-02")})
|
normalizedFactor := normalizer.NormalizeFactor(k, time.Now().Format("2006-01-02"))
|
||||||
normalized[fmt.Sprintf(`(%s trailing $)`, k)] = ledger.Balance{"$": normalizedDelta * normalizedFactor}
|
normalized[fmt.Sprintf(`(%s trailing $)`, k)] = ledger.Balance{"$": normalizedDelta * normalizedFactor}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,15 +68,15 @@ func (n Normalizer) Normalize(deltas ledger.Deltas) ledger.Deltas {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n Normalizer) NormalizeDelta(delta ledger.Delta) ledger.Delta {
|
func (n Normalizer) NormalizeDelta(delta ledger.Delta) ledger.Delta {
|
||||||
delta.Value /= n.NormalizeFactor(delta)
|
delta.Value /= n.NormalizeFactor(delta.Name, delta.Date)
|
||||||
return delta
|
return delta
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n Normalizer) NormalizeFactor(delta ledger.Delta) float64 {
|
func (n Normalizer) NormalizeFactor(name, date string) float64 {
|
||||||
for pattern := range n.m {
|
for pattern := range n.m {
|
||||||
if regexp.MustCompile(pattern).MatchString(delta.Name) {
|
if regexp.MustCompile(pattern).MatchString(name) {
|
||||||
for _, normalize := range n.m[pattern] {
|
for _, normalize := range n.m[pattern] {
|
||||||
if normalize.startDate < delta.Date {
|
if normalize.startDate < date {
|
||||||
return normalize.factor
|
return normalize.factor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Normalizer interface {
|
||||||
|
NormalizeFactor(string, string) float64
|
||||||
|
}
|
||||||
|
|
||||||
type Balances map[string]Balance
|
type Balances map[string]Balance
|
||||||
|
|
||||||
type Balance map[Currency]float64
|
type Balance map[Currency]float64
|
||||||
|
|
@ -246,3 +250,14 @@ func (balance Balance) Debug() string {
|
||||||
}
|
}
|
||||||
return strings.Join(result, " + ")
|
return strings.Join(result, " + ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (balances Balances) Normalize(n Normalizer, date string) Balances {
|
||||||
|
result := make(Balances)
|
||||||
|
for name, balance := range balances {
|
||||||
|
result[name] = make(Balance)
|
||||||
|
for currency, value := range balance {
|
||||||
|
result[name][currency] = value / n.NormalizeFactor(name, date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue