This repository has been archived on 2022-11-30. You can view files and clone it, but cannot push or open issues or pull requests.
tacitus/cmd/watcher/validator.go

127 lines
2.6 KiB
Go

package main
import (
"github.com/kcotugno/tacitus"
"github.com/kcotugno/tacitus/gdax"
"sort"
"time"
)
type ByTradeId []tacitus.Trade
func (t ByTradeId) Len() int { return len(t) }
func (t ByTradeId) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t ByTradeId) Less(i, j int) bool { return t[i].TradeId > t[j].TradeId }
type validator struct {
db tacitus.DatabaseClientService
logger tacitus.Logger
ticker *time.Ticker
done chan bool
}
func (v *validator) stop() {
if v.ticker == nil || v.done == nil {
v.ticker.Stop()
v.done <- true
}
}
func (v *validator) validate(products ...string) {
v.ticker = time.NewTicker(1 * time.Hour)
v.done = make(chan bool)
go func() {
v.emitProducts(products...)
var done bool
for !done {
select {
case <-v.done:
done = true
case <-v.ticker.C:
v.emitProducts(products...)
}
}
v.ticker = nil
v.done = nil
}()
}
func (v *validator) emitProducts(products ...string) {
for _, p := range products {
v.validateProduct(p)
}
}
func (v *validator) validateProduct(product string) {
v.logger.Info("validator: %v", product)
conf, _ := v.db.ConfirmationService().Confirmation(product)
groups, last_id := v.findMissingGroups(product, conf.LastTradeId)
v.getMissingTrades(product, groups)
conf.LastTradeId = last_id
conf.Product = product
if conf.Id == 0 {
v.db.ConfirmationService().CreateConfirmation(conf)
} else {
v.db.ConfirmationService().UpdateConfirmation(conf)
}
v.logger.Info("validator: DONE %v", product)
}
func (v *validator) getMissingTrades(product string, groups [][]int) {
c := gdax.NewPublicClient()
for _, group := range groups {
total := 1 + group[1] - group[0]
v.logger.Info("validator: retrieving %v missing trade(s): %v", total, group)
for i := group[1]; i >= group[0]; i-- {
ts, _ := c.GetTradesBefore(product, i+1)
sort.Sort(ByTradeId(ts))
for _, t := range ts {
if t.TradeId < group[0] && t.TradeId > group[1] {
i = ts[len(ts)-1].TradeId
} else {
v.db.TradeService().CreateTrade(t)
i = t.TradeId
}
}
}
v.logger.Info("validator: DONE")
}
}
func (v *validator) findMissingGroups(product string, starting int) ([][]int, int) {
results, err := v.db.TradeService().TradesAfterAll(product, starting)
if err != nil {
v.logger.Info("Error getting all trades: %v", err)
}
var trade tacitus.Trade
missing := [][]int{}
current := starting
for results.Next() {
trade = results.Value().(tacitus.Trade)
if trade.TradeId != current+1 && trade.TradeId != current {
missing = append(missing, []int{current + 1, trade.TradeId - 1})
}
current = trade.TradeId
}
return missing, current
}