/
resolvers_market.go
120 lines (106 loc) · 3.44 KB
/
resolvers_market.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package gql
import (
"context"
"errors"
"github.com/graph-gophers/graphql-go"
"github.com/lantah/go/services/ticker/internal/tickerdb"
"github.com/lantah/go/services/ticker/internal/utils"
)
// Markets resolves the markets() GraphQL query.
func (r *resolver) Markets(ctx context.Context, args struct {
BaseAssetCode *string
BaseAssetIssuer *string
CounterAssetCode *string
CounterAssetIssuer *string
NumHoursAgo *int32
}) (partialMarkets []*partialMarket, err error) {
numHours, err := validateNumHoursAgo(args.NumHoursAgo)
if err != nil {
return
}
dbMarkets, err := r.db.RetrievePartialMarkets(ctx,
args.BaseAssetCode,
args.BaseAssetIssuer,
args.CounterAssetCode,
args.CounterAssetIssuer,
numHours,
)
if err != nil {
// obfuscating sql errors to avoid exposing underlying
// implementation
err = errors.New("could not retrieve the requested data")
return
}
for _, dbMkt := range dbMarkets {
partialMarkets = append(partialMarkets, dbMarketToPartialMarket(dbMkt))
}
return
}
// Ticker resolves the ticker() GraphQL query (TODO)
func (r *resolver) Ticker(ctx context.Context,
args struct {
Code *string
PairName *string
NumHoursAgo *int32
},
) (partialMarkets []*partialMarket, err error) {
numHours, err := validateNumHoursAgo(args.NumHoursAgo)
if err != nil {
return
}
dbMarkets, err := r.db.RetrievePartialAggMarkets(ctx, args.PairName, numHours)
if err != nil {
// obfuscating sql errors to avoid exposing underlying
// implementation
err = errors.New("could not retrieve the requested data")
return
}
for _, dbMkt := range dbMarkets {
partialMarkets = append(partialMarkets, dbMarketToPartialMarket(dbMkt))
}
return
}
// validateNumHoursAgo validates if the numHoursAgo parameter is within an acceptable
// time range (at most 168 hours ago = 7 days)
func validateNumHoursAgo(n *int32) (int, error) {
if n == nil {
return 24, nil // default numHours = 24
}
if *n <= 168 {
return int(*n), nil
}
return 0, errors.New("numHoursAgo cannot be greater than 168 (7 days)")
}
// dbMarketToPartialMarket converts a tickerdb.PartialMarket to a *partialMarket
func dbMarketToPartialMarket(dbMarket tickerdb.PartialMarket) *partialMarket {
spread, spreadMidPoint := utils.CalcSpread(dbMarket.HighestBid, dbMarket.LowestAsk)
os := orderbookStats{
BidCount: BigInt(dbMarket.NumBids),
BidVolume: dbMarket.BidVolume,
BidMax: dbMarket.HighestBid,
AskCount: BigInt(dbMarket.NumAsks),
AskVolume: dbMarket.AskVolume,
AskMin: dbMarket.LowestAsk,
Spread: spread,
SpreadMidPoint: spreadMidPoint,
}
return &partialMarket{
TradePair: dbMarket.TradePairName,
BaseAssetCode: dbMarket.BaseAssetCode,
BaseAssetIssuer: dbMarket.BaseAssetIssuer,
CounterAssetCode: dbMarket.CounterAssetCode,
CounterAssetIssuer: dbMarket.CounterAssetIssuer,
BaseVolume: dbMarket.BaseVolume,
CounterVolume: dbMarket.CounterVolume,
TradeCount: dbMarket.TradeCount,
Open: dbMarket.Open,
Low: dbMarket.Low,
High: dbMarket.High,
Change: dbMarket.Change,
Close: dbMarket.Close,
IntervalStart: graphql.Time{Time: dbMarket.IntervalStart},
FirstLedgerCloseTime: graphql.Time{Time: dbMarket.FirstLedgerCloseTime},
LastLedgerCloseTime: graphql.Time{Time: dbMarket.LastLedgerCloseTime},
OrderbookStats: os,
}
}