Skip to content

Commit

Permalink
feat: added user ordered sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
achannarasappa committed Feb 14, 2021
1 parent d66e81a commit 6d522e7
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 10 deletions.
11 changes: 10 additions & 1 deletion README.md
Expand Up @@ -74,7 +74,7 @@ ticker -w NET,AAPL,TSLA
| |--show-fundamentals||display open price, previous close, and day range |
| |--show-separator||layout with separators between each quote|
| |--show-summary||show total day change, total value, and total value change|
| |--sort||sort quotes on the UI. Set `alpha` to sort by ticker name. Set `value` to sort by position value. Default is sort by change percent|
| |--sort||sort quotes on the UI - options are change percent (default), `alpha`, `value`, and `user`|
| |--proxy||proxy URL for requests (default is none)|

## Configuration
Expand Down Expand Up @@ -116,6 +116,15 @@ With `--show-summary`, `--show-tags`, `--show-fundamentals`, and `--show-separa

<img src="./docs/ticker-all-options.png" />

### Sorting

It's possible to set a custom sort order with the `--sort` flag or `sort:` config option with these options:

* Default - change percent with closed markets at the end
* `alpha` to sort alphabetically by symbol
* `value` to sort by position value
* `user` to sort by the order defined in configuration with positions on top then lots

### Currency Conversion

`ticker` supports converting from the exchange's currency to a local currency. This can be set by setting the `currency` property in `.ticker.yaml` to a [ISO 4217 3-digit currency code](https://docs.1010data.com/1010dataReferenceManual/DataTypesAndFormats/currencyUnitCodes.html).
Expand Down
16 changes: 9 additions & 7 deletions internal/position/position.go
Expand Up @@ -29,9 +29,10 @@ type PositionSummary struct {
}

type AggregatedLot struct {
Symbol string
Cost float64
Quantity float64
Symbol string
Cost float64
Quantity float64
OrderIndex int
}

func GetLots(lots []c.Lot) map[string]AggregatedLot {
Expand All @@ -42,14 +43,15 @@ func GetLots(lots []c.Lot) map[string]AggregatedLot {

aggregatedLots := gubrak.
From(lots).
Reduce(func(acc map[string]AggregatedLot, lot c.Lot) map[string]AggregatedLot {
Reduce(func(acc map[string]AggregatedLot, lot c.Lot, i int) map[string]AggregatedLot {

aggregatedLot, ok := acc[lot.Symbol]
if !ok {
acc[lot.Symbol] = AggregatedLot{
Symbol: lot.Symbol,
Cost: lot.UnitCost * lot.Quantity,
Quantity: lot.Quantity,
Symbol: lot.Symbol,
Cost: lot.UnitCost * lot.Quantity,
Quantity: lot.Quantity,
OrderIndex: i,
}
return acc
}
Expand Down
4 changes: 2 additions & 2 deletions internal/position/position_test.go
Expand Up @@ -20,8 +20,8 @@ var _ = Describe("Position", func() {
}
output := GetLots(input)
expected := map[string]AggregatedLot{
"ABNB": {Symbol: "ABNB", Cost: 5110, Quantity: 35},
"ARKW": {Symbol: "ARKW", Cost: 6090, Quantity: 40},
"ABNB": {Symbol: "ABNB", Cost: 5110, Quantity: 35, OrderIndex: 0},
"ARKW": {Symbol: "ARKW", Cost: 6090, Quantity: 40, OrderIndex: 1},
}
Expect(output).To(Equal(expected))
})
Expand Down
22 changes: 22 additions & 0 deletions internal/sorter/sorter.go
Expand Up @@ -20,6 +20,28 @@ func NewSorter(sort string) Sorter {
var sortDict = map[string]Sorter{
"alpha": sortByTicker,
"value": sortByValue,
"user": sortByUser,
}

func sortByUser(quotes []Quote, positions map[string]Position) []Quote {

quoteCount := len(quotes)

if quoteCount <= 0 {
return quotes
}

result := gubrak.
From(quotes).
OrderBy(func(v Quote) int {
if p, ok := positions[v.Symbol]; ok {
return p.AggregatedLot.OrderIndex
}
return quoteCount
}).
Result()

return (result).([]Quote)
}

func sortByTicker(quotes []Quote, positions map[string]Position) []Quote {
Expand Down
30 changes: 30 additions & 0 deletions internal/sorter/sorter_test.go
Expand Up @@ -69,9 +69,15 @@ var _ = Describe("Sorter", func() {
positions := map[string]Position{
"BTC-USD": {
Value: 50000.0,
AggregatedLot: AggregatedLot{
OrderIndex: 1,
},
},
"GOOG": {
Value: 2523.53,
AggregatedLot: AggregatedLot{
OrderIndex: 0,
},
},
}
When("providing no sort parameter", func() {
Expand Down Expand Up @@ -119,6 +125,21 @@ var _ = Describe("Sorter", func() {
Expect(sortedQuotes).To(Equal(expected))
})
})
When("providing \"user\" as a sort parameter", func() {
It("should sort by the user defined order for positions and watchlist", func() {
sorter := NewSorter("user")

sortedQuotes := sorter(quotes, positions)
expected := []Quote{
googleQuote,
bitcoinQuote,
twQuote,
msftQuote,
}

Expect(sortedQuotes).To(Equal(expected))
})
})
When("providing no quotes", func() {
When("default sorter", func() {
It("should return no quotes", func() {
Expand All @@ -142,6 +163,15 @@ var _ = Describe("Sorter", func() {
It("should return no quotes", func() {
sorter := NewSorter("value")

sortedQuotes := sorter([]Quote{}, map[string]Position{})
expected := []Quote{}
Expect(sortedQuotes).To(Equal(expected))
})
})
When("user sorter", func() {
It("should return no quotes", func() {
sorter := NewSorter("user")

sortedQuotes := sorter([]Quote{}, map[string]Position{})
expected := []Quote{}
Expect(sortedQuotes).To(Equal(expected))
Expand Down

0 comments on commit 6d522e7

Please sign in to comment.