Skip to content

Commit

Permalink
Merge pull request #34 from bonedaddy/charts
Browse files Browse the repository at this point in the history
Charts
  • Loading branch information
bonedaddy authored Jan 11, 2021
2 parents a3a2d33 + 4bcec12 commit 35ff410
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 7 deletions.
8 changes: 4 additions & 4 deletions .scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

if [ ! -d release ]; then
mkdir release
else
rm -rf release/*
fi

VERSION=`git describe --tags`

go build -o release/gondx -ldflags "-X main.Version=$VERSION" ./cmd/gondx

docker build --build-arg VERSION=$VERSION -t bonedaddy/gondx:$VERSION .
docker image tag bonedaddy/gondx:$VERSION bonedaddy/gondx:latest

docker image save bonedaddy/gondx:$VERSION --output release/gondx-docker_$VERSION.tar

go build -o release/gondx -ldflags "-X main.Version=$VERSION" ./cmd/gondx

ls ./release/* > files
for i in $(cat files); do
sha256sum "$i" > "$i.sha256"
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
FROM golang:1.15-alpine3.12 AS build-env
ARG VERSION
RUN apk add build-base linux-headers
ARG VERSION
ENV BUILD_HOME=/BUILD
RUN mkdir -p ${BUILD_HOME}
ADD . ${BUILD_HOME}
WORKDIR ${BUILD_HOME}

ADD . ${BUILD_HOME}
RUN go mod download
RUN go build -o /bin/gondx \
-ldflags "-X main.Version=$VERSION" \
./cmd/gondx

FROM alpine:3.12
RUN apk add --no-cache tini
COPY --from=build-env /bin/gondx /bin/gondx
ENTRYPOINT ["/bin/gondx", "--config", "/config.yml" ]
CMD [ "--startup.sleep", "discord", "ndx-bot", "--update.database" ]
9 changes: 9 additions & 0 deletions db/price.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ func (d *Database) GetAllPrices(asset string) ([]*Price, error) {
return prices, d.db.Model(&Price{}).Where("type = ?", asset).Find(&prices).Error
}

// PricesInRange returns all prices items in the given range
func (d *Database) PricesInRange(asset string, windowInDays int) ([]*Price, error) {
if !IsValidAsset(asset) {
return nil,
ErrInvalidAsset
}
return d.windowRangeQuery(asset, windowInDays)
}

// PriceAvgInRange returns the average price of the given asset during the last N days
func (d *Database) PriceAvgInRange(asset string, windowInDays int) (float64, error) {
if !IsValidAsset(asset) {
Expand Down
153 changes: 153 additions & 0 deletions discord/charts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package discord

import (
"bytes"
"log"
"strings"

"github.com/bonedaddy/dgc"
"github.com/bonedaddy/go-indexed/db"
"github.com/wcharczuk/go-chart/v2"
"github.com/wcharczuk/go-chart/v2/drawing"
)

func (c *Client) priceWindowChart(ctx *dgc.Ctx) {

arguments := ctx.Arguments
pair := arguments.Get(0).Raw()
window, err := arguments.Get(1).AsInt()
if err != nil {
ctx.RespondText("window argument is not a number")
return
}
var (
prices []*db.Price
)
// valid the allowed currencies
switch strings.ToLower(pair) {
case "defi5-dai":
prices, err = c.db.PricesInRange("defi5", window)
if err != nil {
ctx.RespondText("failed to get price")
log.Println("defi5 dai price change fetch failed: ", err)
return
}
case "cc10-dai":
prices, err = c.db.PricesInRange("cc10", window)
if err != nil {
ctx.RespondText("failed to get price")
log.Println("cc10 dai price change fetch failed: ", err)
return
}
case "ndx-dai":
prices, err = c.db.PricesInRange("ndx", window)
if err != nil {
ctx.RespondText("failed to get price")
log.Println("ndx dai price change fetch failed: ", err)
return
}
case "eth-dai":
prices, err = c.db.PricesInRange("eth", window)
if err != nil {
ctx.RespondText("failed to get price")
log.Println("eth dai price change fetch failed: ", err)
return
}
default:
ctx.RespondText("invalid currency requested must be one of: defi5-dai, cc10-dai, eth-dai, ndx-dai")
return
}
priceSeries := chart.TimeSeries{
Name: "price",
Style: chart.Style{
StrokeColor: chart.GetDefaultColor(0),
},
}
// records prices at every hour
priceHourSeries := chart.TimeSeries{
Style: chart.Style{
StrokeColor: chart.GetDefaultColor(0),
},
}
var (
// set = make(map[int]bool)
hourSet = make(map[int]map[int]bool)
minSet = make(map[int]map[int]map[int]bool)
// track days -> hours
)
for _, price := range prices {
if hourSet[price.CreatedAt.Day()] == nil {
hourSet[price.CreatedAt.Day()] = make(map[int]bool)
}
if minSet[price.CreatedAt.Day()] == nil {
minSet[price.CreatedAt.Day()] = make(map[int]map[int]bool)
}
if minSet[price.CreatedAt.Day()][price.CreatedAt.Hour()] == nil {
minSet[price.CreatedAt.Day()][price.CreatedAt.Hour()] = make(map[int]bool)
}
// make sure we only update the hour set one per hour
if !hourSet[price.CreatedAt.Day()][price.CreatedAt.Hour()] {
priceHourSeries.XValues = append(priceHourSeries.XValues, price.CreatedAt)
priceHourSeries.YValues = append(priceHourSeries.YValues, price.USDPrice)
hourSet[price.CreatedAt.Day()][price.CreatedAt.Hour()] = true
}
// make sure we only record one price per minute
if !minSet[price.CreatedAt.Day()][price.CreatedAt.Hour()][price.CreatedAt.Minute()] {
priceSeries.XValues = append(priceSeries.XValues, price.CreatedAt)
priceSeries.YValues = append(priceSeries.YValues, price.USDPrice)
}
}

hourlySMASeries := &chart.SMASeries{
Name: "hourly sma",
Period: window,
Style: chart.Style{
StrokeColor: drawing.ColorRed,
},
InnerSeries: priceHourSeries,
}
hourlyEMASeries := &chart.EMASeries{
Name: "hourly ema",
Period: window,
Style: chart.Style{
StrokeColor: drawing.ColorGreen,
},
InnerSeries: priceHourSeries,
}

graph := chart.Chart{
Background: chart.Style{
Padding: chart.Box{
Left: 45,
},
},
XAxis: chart.XAxis{
TickPosition: chart.TickPositionBetweenTicks,
// ensure we render date timestamps with minute granularity
ValueFormatter: chart.TimeMinuteValueFormatter,
},
Series: []chart.Series{
priceSeries,
hourlySMASeries,
hourlyEMASeries,
},
}

//note we have to do this as a separate step because we need a reference to graph
graph.Elements = []chart.Renderable{
chart.LegendLeft(&graph),
}

buffer := bytes.NewBuffer(nil)
if err := graph.Render(chart.PNG, buffer); err != nil {
log.Println("failed to render SMA: ", err)
ctx.RespondText("failed to render SMA")
return
}

if _, err := ctx.Session.ChannelFileSend(ctx.Event.ChannelID, "chart.png", buffer); err != nil {
log.Println("failed to upload chart: ", err)
ctx.RespondText("failed to upload chart")
return
}
}
4 changes: 4 additions & 0 deletions discord/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ func NewClient(ctx context.Context, cfg *Config, bc *bclient.Client, db *db.Data
Example: " uniswap price-change defi5-dai 10 (returns the price change over the last 10 days for defi5)",
Handler: client.uniswapPercentChangeHandler,
},
&dgc.Command{
Name: "price-chart",
Handler: client.priceWindowChart,
},
},

Handler: func(ctx *dgc.Ctx) {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/shopspring/decimal v1.2.0
github.com/stretchr/testify v1.5.1
github.com/urfave/cli/v2 v2.3.0
github.com/wcharczuk/go-chart/v2 v2.1.0
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
gopkg.in/yaml.v2 v2.3.0
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
Expand Down Expand Up @@ -77,8 +78,11 @@ github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dT
github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
Expand Down Expand Up @@ -124,6 +128,7 @@ github.com/jackc/pgconn v1.8.0 h1:FmjZ0rOyXTr1wfWs45i4a9vjnjWUAGpMuQLD9OSs+lw=
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2 h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
Expand Down Expand Up @@ -188,11 +193,13 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
Expand All @@ -202,6 +209,7 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
Expand Down Expand Up @@ -287,6 +295,8 @@ github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/zekroTJA/timedmap v0.0.0-20200518230343-de9b879d109a h1:S8UfZYz3TbkwO8bZ1UE3miiEjh/KSi4tZYwX1A/omC4=
Expand Down Expand Up @@ -314,6 +324,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20200801112145-973feb4309de/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
Expand Down

0 comments on commit 35ff410

Please sign in to comment.