Support hardcoded starting prices.
All checks were successful
Build & Test / Main (push) Successful in 1m0s
All checks were successful
Build & Test / Main (push) Successful in 1m0s
The Coindesk API doesn't have data going all the way back. But since history isn't changing, we can simply put in known prices. Also, extend the CDPR cells to have four digits instead of just two.
This commit is contained in:
parent
4d5dcc46d2
commit
f67323c5f4
@ -28,6 +28,12 @@ defaults:
|
|||||||
time: 2019-12-31T16:00:00-08:00
|
time: 2019-12-31T16:00:00-08:00
|
||||||
- name: 2017-
|
- name: 2017-
|
||||||
time: 2016-12-31T16:00:00-08:00
|
time: 2016-12-31T16:00:00-08:00
|
||||||
|
- name: 2013-
|
||||||
|
time: 2012-12-31T16:00:00-08:00
|
||||||
|
startingPrice: 13.30
|
||||||
|
- name: 2011-
|
||||||
|
time: 2010-12-31T16:00:00-08:00
|
||||||
|
startingPrice: 0.30
|
||||||
|
|
||||||
assets:
|
assets:
|
||||||
ETH:
|
ETH:
|
||||||
@ -44,6 +50,11 @@ assets:
|
|||||||
value: 20000
|
value: 20000
|
||||||
- name: $25k
|
- name: $25k
|
||||||
value: 25000
|
value: 25000
|
||||||
|
constantBases:
|
||||||
|
- name: 2020-
|
||||||
|
time: 2019-12-31T16:00:00-08:00
|
||||||
|
- name: 2017-
|
||||||
|
time: 2016-12-31T16:00:00-08:00
|
||||||
LTC:
|
LTC:
|
||||||
goals:
|
goals:
|
||||||
- name: $100
|
- name: $100
|
||||||
|
94
moon/moon.go
94
moon/moon.go
@ -2,6 +2,8 @@ package moon
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -74,30 +76,10 @@ func (m *Math) Refresh(ctx context.Context) (err error) {
|
|||||||
tasks.WithMaxGoroutines(len(m.Columns))
|
tasks.WithMaxGoroutines(len(m.Columns))
|
||||||
//tasks.WithMaxGoroutines(1)
|
//tasks.WithMaxGoroutines(1)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
for i := range m.Columns {
|
for i := range m.Columns {
|
||||||
c := &m.Columns[i]
|
c := &m.Columns[i]
|
||||||
tasks.Go(func() error {
|
tasks.Go(func() error {
|
||||||
c.StartingDate = c.Base.From(now)
|
return c.project(ctx, m, now)
|
||||||
nextDay := c.StartingDate.Add(time.Hour * 24)
|
|
||||||
resp, err := coindesk.GetPriceValues(ctx,
|
|
||||||
m.Asset, c.StartingDate, nextDay)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(resp.Data.Entries) == 0 {
|
|
||||||
c.Projections.Dates = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
c.StartingPrice = resp.Data.Entries[0].Price
|
|
||||||
c.Gain = float64(m.CurrentPrice) / float64(c.StartingPrice)
|
|
||||||
days := now.Sub(c.StartingDate).Hours() / 24
|
|
||||||
c.CDPR = CDPR(days, c.Gain)
|
|
||||||
c.Projections = ProjectDates(
|
|
||||||
now, float64(m.CurrentPrice),
|
|
||||||
c.CDPR, m.Goals,
|
|
||||||
)
|
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
err = tasks.Wait()
|
err = tasks.Wait()
|
||||||
@ -114,27 +96,49 @@ type Column struct {
|
|||||||
Projections Projection
|
Projections Projection
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultGoals = []Goal{
|
func (c *Column) project(ctx context.Context, m *Math, now time.Time) (err error) {
|
||||||
{"$100k", 100000},
|
err = c.fillStartingPrice(ctx, m.Asset, now)
|
||||||
{"$150k", 150000},
|
if err != nil {
|
||||||
{"$200k", 200000},
|
return
|
||||||
{"$250k", 250000},
|
}
|
||||||
{"$300k", 300000},
|
|
||||||
{"$500k", 500000},
|
c.Gain = float64(m.CurrentPrice) / float64(c.StartingPrice)
|
||||||
{"$1m", 1000000},
|
days := now.Sub(c.StartingDate).Hours() / 24
|
||||||
|
c.CDPR = CDPR(days, c.Gain)
|
||||||
|
c.Projections = ProjectDates(
|
||||||
|
now, float64(m.CurrentPrice),
|
||||||
|
c.CDPR, m.Goals,
|
||||||
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultConstantBases = []ConstantBase{
|
func (c *Column) fillStartingPrice(
|
||||||
{"2020-", time.Unix(1577836800, 0)},
|
ctx context.Context, asset coindesk.Asset, now time.Time,
|
||||||
{"2017-", time.Unix(1483228800, 0)},
|
) error {
|
||||||
|
// if base provides a hardcoded starting price, use it
|
||||||
|
c.StartingDate = c.Base.From(now)
|
||||||
|
c.StartingPrice = coindesk.Price(c.Base.GetStartingPrice())
|
||||||
|
if c.StartingPrice != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, look up the starting price via Coindesk
|
||||||
|
nextDay := c.StartingDate.Add(time.Hour * 24)
|
||||||
|
resp, err := coindesk.GetPriceValues(ctx, asset, c.StartingDate, nextDay)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("getting price for %s on %v: %w",
|
||||||
|
asset, c.StartingDate, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(resp.Data.Entries) == 0 {
|
||||||
|
c.Projections.Dates = nil
|
||||||
|
return errEmptyPriceEntries
|
||||||
|
}
|
||||||
|
c.StartingPrice = resp.Data.Entries[0].Price
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultRelativeBases = []RelativeBase{
|
var errEmptyPriceEntries = errors.New("price values response has no entries")
|
||||||
{"Month", time.Duration(-30) * time.Hour * 24},
|
|
||||||
{"Quarter", time.Duration(-90) * time.Hour * 24},
|
|
||||||
{"Half-Year", time.Duration(-182) * time.Hour * 24},
|
|
||||||
{"Year", time.Duration(-365) * time.Hour * 24},
|
|
||||||
}
|
|
||||||
|
|
||||||
type Goal struct {
|
type Goal struct {
|
||||||
Name string `koanf:"name"`
|
Name string `koanf:"name"`
|
||||||
@ -145,12 +149,14 @@ type Goal struct {
|
|||||||
type Base interface {
|
type Base interface {
|
||||||
From(now time.Time) time.Time
|
From(now time.Time) time.Time
|
||||||
Label() string
|
Label() string
|
||||||
|
GetStartingPrice() float64
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantBase is a base that is a constant time, e.g. 2020-01-01.
|
// ConstantBase is a base that is a constant time, e.g. 2020-01-01.
|
||||||
type ConstantBase struct {
|
type ConstantBase struct {
|
||||||
Name string `koanf:"name"`
|
Name string `koanf:"name"`
|
||||||
Time time.Time `koanf:"time"`
|
Time time.Time `koanf:"time"`
|
||||||
|
StartingPrice float64 `koanf:"startingPrice"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cb ConstantBase) From(_ time.Time) time.Time {
|
func (cb ConstantBase) From(_ time.Time) time.Time {
|
||||||
@ -161,6 +167,10 @@ func (cb ConstantBase) Label() string {
|
|||||||
return cb.Name
|
return cb.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cb ConstantBase) GetStartingPrice() float64 {
|
||||||
|
return cb.StartingPrice
|
||||||
|
}
|
||||||
|
|
||||||
// RelativeBase is a base that is relative, e.g. "90 days ago."
|
// RelativeBase is a base that is relative, e.g. "90 days ago."
|
||||||
type RelativeBase struct {
|
type RelativeBase struct {
|
||||||
Name string `koanf:"name"`
|
Name string `koanf:"name"`
|
||||||
@ -175,3 +185,7 @@ func (rb RelativeBase) From(now time.Time) time.Time {
|
|||||||
func (rb RelativeBase) Label() string {
|
func (rb RelativeBase) Label() string {
|
||||||
return rb.Name
|
return rb.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rb RelativeBase) GetStartingPrice() float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
@ -11,6 +11,14 @@ func TestCDPR(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestProjection(t *testing.T) {
|
func TestProjection(t *testing.T) {
|
||||||
p := moon.ProjectDates(time.Now(), 68900, 1.0055, moon.DefaultGoals)
|
p := moon.ProjectDates(time.Now(), 68900, 1.0055, []moon.Goal{
|
||||||
|
{"$100k", 100000},
|
||||||
|
{"$150k", 150000},
|
||||||
|
{"$200k", 200000},
|
||||||
|
{"$250k", 250000},
|
||||||
|
{"$300k", 300000},
|
||||||
|
{"$500k", 500000},
|
||||||
|
{"$1m", 1000000},
|
||||||
|
})
|
||||||
_ = p
|
_ = p
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ func refillProjections(m *Model) {
|
|||||||
|
|
||||||
func renderEntries(c moon.Column) (entries []string) {
|
func renderEntries(c moon.Column) (entries []string) {
|
||||||
entries = append(entries, fmt.Sprintf("$%.2f", c.StartingPrice))
|
entries = append(entries, fmt.Sprintf("$%.2f", c.StartingPrice))
|
||||||
entries = append(entries, fmt.Sprintf("%.2f%%", (c.CDPR-1)*100))
|
entries = append(entries, fmt.Sprintf("%.4f%%", (c.CDPR-1)*100))
|
||||||
never := c.CDPR <= 1
|
never := c.CDPR <= 1
|
||||||
for i := range c.Projections.Dates {
|
for i := range c.Projections.Dates {
|
||||||
var cell string
|
var cell string
|
||||||
|
Loading…
Reference in New Issue
Block a user