portfolio: clean up fixes #243

pull/250/head
Miguel Mota 3 years ago committed by Simon Roberts
parent b5b68833f5
commit 0e956d6358
No known key found for this signature in database
GPG Key ID: 0F30F99E6B771FD4

@ -647,10 +647,8 @@ func (ct *Cointop) loadPortfolioHoldingsFromConfig(holdingsIfc []interface{}) er
buyPrice := 0.0 buyPrice := 0.0
if len(tupleIfc) >= 3 { if len(tupleIfc) >= 3 {
if parsePrice, err := ct.InterfaceToFloat64(tupleIfc[2]); err != nil { if buyPrice, err = ct.InterfaceToFloat64(tupleIfc[2]); err != nil {
return err return err
} else {
buyPrice = parsePrice
} }
} }

@ -302,19 +302,19 @@ func CurrencySymbol(currency string) string {
return "?" return "?"
} }
func (ct *Cointop) Convert(convertFrom string, convertTo string, amount float64) (float64, error) { // Convert converts an amount to another currency type
func (ct *Cointop) Convert(convertFrom, convertTo string, amount float64) (float64, error) {
convertFrom = strings.ToLower(convertFrom) convertFrom = strings.ToLower(convertFrom)
convertTo = strings.ToLower(convertTo) convertTo = strings.ToLower(convertTo)
var rate float64
if convertFrom == convertTo { if convertFrom == convertTo {
rate = 1.0 return amount, nil
} else { }
crate, err := ct.api.GetExchangeRate(convertFrom, convertTo, true)
rate, err := ct.api.GetExchangeRate(convertFrom, convertTo, true)
if err != nil { if err != nil {
return 0, err return 0, err
} }
rate = crate
}
return rate * amount, nil return rate * amount, nil
} }

@ -328,9 +328,9 @@ func (ct *Cointop) SetKeybindingAction(shortcutKey string, action string) error
case "sort_column_cost": case "sort_column_cost":
fn = ct.Sortfn("cost", true) fn = ct.Sortfn("cost", true)
case "sort_column_pnl": case "sort_column_pnl":
fn = ct.Sortfn("profit", true) fn = ct.Sortfn("pnl", true)
case "sort_column_pnl_percent": case "sort_column_pnl_percent":
fn = ct.Sortfn("profit_percent", true) fn = ct.Sortfn("pnl_percent", true)
default: default:
fn = ct.Keyfn(ct.Noop) fn = ct.Keyfn(ct.Noop)
} }

@ -37,8 +37,8 @@ var SupportedPortfolioTableHeaders = []string{
"last_updated", "last_updated",
"cost_price", "cost_price",
"cost", "cost",
"profit", "pnl",
"profit_percent", "pnl_percent",
} }
// DefaultPortfolioTableHeaders are the default portfolio table header columns // DefaultPortfolioTableHeaders are the default portfolio table header columns
@ -53,12 +53,23 @@ var DefaultPortfolioTableHeaders = []string{
"24h_change", "24h_change",
"7d_change", "7d_change",
"percent_holdings", "percent_holdings",
"cost_price",
"cost",
"pnl",
"pnl_percent",
"last_updated", "last_updated",
} }
// HiddenBalanceChars are the characters to show when hidding balances // HiddenBalanceChars are the characters to show when hidding balances
var HiddenBalanceChars = "********" var HiddenBalanceChars = "********"
var costColumns = map[string]bool{
"cost_price": true,
"cost": true,
"pnl": true,
"pnl_percent": true,
}
// ValidPortfolioTableHeader returns the portfolio table headers // ValidPortfolioTableHeader returns the portfolio table headers
func (ct *Cointop) ValidPortfolioTableHeader(name string) bool { func (ct *Cointop) ValidPortfolioTableHeader(name string) bool {
for _, v := range SupportedPortfolioTableHeaders { for _, v := range SupportedPortfolioTableHeaders {
@ -84,6 +95,25 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
headers := ct.GetPortfolioTableHeaders() headers := ct.GetPortfolioTableHeaders()
ct.ClearSyncMap(&ct.State.tableColumnWidths) ct.ClearSyncMap(&ct.State.tableColumnWidths)
ct.ClearSyncMap(&ct.State.tableColumnAlignLeft) ct.ClearSyncMap(&ct.State.tableColumnAlignLeft)
displayCostColumns := false
for _, coin := range ct.State.coins {
if coin.BuyPrice > 0 && coin.BuyCurrency != "" {
displayCostColumns = true
break
}
}
if !displayCostColumns {
filtered := make([]string, 0)
for _, header := range headers {
if _, ok := costColumns[header]; !ok {
filtered = append(filtered, header)
}
}
headers = filtered
}
for _, coin := range ct.State.coins { for _, coin := range ct.State.coins {
leftMargin := 1 leftMargin := 1
rightMargin := 1 rightMargin := 1
@ -332,7 +362,6 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
cost = costPrice * coin.Holdings cost = costPrice * coin.Holdings
} }
} }
// text := ct.FormatPrice(cost)
text := humanize.FixedMonetaryf(cost, 2) text := humanize.FixedMonetaryf(cost, 2)
if ct.State.hidePortfolioBalances { if ct.State.hidePortfolioBalances {
text = HiddenBalanceChars text = HiddenBalanceChars
@ -352,7 +381,7 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
Color: ct.colorscheme.TableColumnPrice, Color: ct.colorscheme.TableColumnPrice,
Text: text, Text: text,
}) })
case "profit": case "pnl":
text := "" text := ""
colorProfit := ct.colorscheme.TableColumnChange colorProfit := ct.colorscheme.TableColumnChange
if coin.BuyPrice > 0 && coin.BuyCurrency != "" { if coin.BuyPrice > 0 && coin.BuyCurrency != "" {
@ -385,7 +414,7 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
Color: colorProfit, Color: colorProfit,
Text: text, Text: text,
}) })
case "profit_percent": case "pnl_percent":
profitPercent := 0.0 profitPercent := 0.0
if coin.BuyPrice > 0 && coin.BuyCurrency != "" { if coin.BuyPrice > 0 && coin.BuyCurrency != "" {
costPrice, err := ct.Convert(coin.BuyCurrency, ct.State.currencyConversion, coin.BuyPrice) costPrice, err := ct.Convert(coin.BuyCurrency, ct.State.currencyConversion, coin.BuyPrice)
@ -812,8 +841,7 @@ func (ct *Cointop) PrintHoldingsTable(options *TablePrintOptions) error {
records := make([][]string, len(holdings)) records := make([][]string, len(holdings))
symbol := ct.CurrencySymbol() symbol := ct.CurrencySymbol()
// TODO: buy_price, buy_currency, profit, profit_percent, etc headers := []string{"name", "symbol", "price", "holdings", "balance", "24h%", "%holdings", "buy_price", "buy_currency", "pnl", "pnl_percent"}
headers := []string{"name", "symbol", "price", "holdings", "balance", "24h%", "%holdings"}
if len(filterCols) > 0 { if len(filterCols) > 0 {
for _, col := range filterCols { for _, col := range filterCols {
valid := false valid := false

@ -72,9 +72,9 @@ func (ct *Cointop) Sort(sortBy string, desc bool, list []*Coin, renderHeaders bo
return a.BuyPrice < b.BuyPrice return a.BuyPrice < b.BuyPrice
case "cost": case "cost":
return (a.BuyPrice * a.Holdings) < (b.BuyPrice * b.Holdings) // TODO: convert? return (a.BuyPrice * a.Holdings) < (b.BuyPrice * b.Holdings) // TODO: convert?
case "profit": case "pnl":
return (a.Price - a.BuyPrice) < (b.Price - b.BuyPrice) return (a.Price - a.BuyPrice) < (b.Price - b.BuyPrice)
case "profit_percent": case "pnl_percent":
return (a.Price - a.BuyPrice) < (b.Price - b.BuyPrice) return (a.Price - a.BuyPrice) < (b.Price - b.BuyPrice)
default: default:
return a.Rank < b.Rank return a.Rank < b.Rank

@ -133,17 +133,17 @@ var HeaderColumns = map[string]*HeaderColumn{
}, },
"cost": { "cost": {
Slug: "cost", Slug: "cost",
Label: "cost[!]", Label: "[!]cost",
PlainLabel: "cost", PlainLabel: "cost",
}, },
"profit": { "pnl": {
Slug: "profit", Slug: "pnl",
Label: "PNL[@]", Label: "[@]PNL",
PlainLabel: "PNL", PlainLabel: "PNL",
}, },
"profit_percent": { "pnl_percent": {
Slug: "profit_percent", Slug: "pnl_percent",
Label: "PNL%[#]", Label: "[#]PNL%",
PlainLabel: "PNL%", PlainLabel: "PNL%",
}, },
} }
@ -231,7 +231,7 @@ func (ct *Cointop) UpdateTableHeader() error {
} }
leftAlign := ct.GetTableColumnAlignLeft(col) leftAlign := ct.GetTableColumnAlignLeft(col)
switch col { switch col {
case "price", "balance", "profit", "cost": case "price", "balance", "pnl", "cost":
label = fmt.Sprintf("%s%s", ct.CurrencySymbol(), label) label = fmt.Sprintf("%s%s", ct.CurrencySymbol(), label)
} }
if leftAlign { if leftAlign {

@ -200,12 +200,12 @@ draft: false
- `cost_price` the price and currency that the coins were purchased at - `cost_price` the price and currency that the coins were purchased at
- `cost` the cost (in the current currency) of the coins - `cost` the cost (in the current currency) of the coins
- `profit` the PNL of the coins (current value vs original cost) - `pnl` the PNL of the coins (current value vs original cost)
- `profit_percent` the PNL of the coins as a fraction of the original cost - `pnl_percent` the PNL of the coins as a fraction of the original cost
With the holdings above, and the currency set to GBP (British Pounds) cointop will look something like this: With the holdings above, and the currency set to GBP (British Pounds) cointop will look something like this:
![Screen Shot 2021-10-22 at 8 41 21 am](https://user-images.githubusercontent.com/122371/138361142-8e1f32b5-ca24-471d-a628-06968f07c65f.png) ![portfolio profit and loss](https://user-images.githubusercontent.com/122371/138361142-8e1f32b5-ca24-471d-a628-06968f07c65f.png)
## How do I hide my portfolio balances (private mode)? ## How do I hide my portfolio balances (private mode)?

@ -161,7 +161,7 @@ func (s *Service) GetExchangeRates(cached bool) (*types.ExchangeRatesItem, error
} }
// GetExchangeRate gets the current excange rate between two currencies // GetExchangeRate gets the current excange rate between two currencies
func (s *Service) GetExchangeRate(convertFrom string, convertTo string, cached bool) (float64, error) { func (s *Service) GetExchangeRate(convertFrom, convertTo string, cached bool) (float64, error) {
convertFrom = strings.ToLower(convertFrom) convertFrom = strings.ToLower(convertFrom)
convertTo = strings.ToLower(convertTo) convertTo = strings.ToLower(convertTo)
if convertFrom == convertTo { if convertFrom == convertTo {

@ -432,7 +432,7 @@ func getChartInterval(start, end int64) string {
} }
// GetExchangeRate gets the current excange rate between two currencies // GetExchangeRate gets the current excange rate between two currencies
func (s *Service) GetExchangeRate(convertFrom string, convertTo string, cached bool) (float64, error) { func (s *Service) GetExchangeRate(convertFrom, convertTo string, cached bool) (float64, error) {
if convertFrom == convertTo { if convertFrom == convertTo {
return 1.0, nil return 1.0, nil
} }

@ -16,5 +16,5 @@ type Interface interface {
CoinLink(name string) string CoinLink(name string) string
SupportedCurrencies() []string SupportedCurrencies() []string
Price(name string, convert string) (float64, error) Price(name string, convert string) (float64, error)
GetExchangeRate(convertFrom string, convertTo string, cached bool) (float64, error) // I don't love this caching GetExchangeRate(convertFrom, convertTo string, cached bool) (float64, error) // I don't love this caching
} }

Loading…
Cancel
Save