github.com/diadata-org/diadata@v1.4.593/pkg/model/ForeignQuotation.go (about) 1 package models 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "strconv" 8 "time" 9 10 clientInfluxdb "github.com/influxdata/influxdb1-client/v2" 11 ) 12 13 const influxDbForeignQuotationTable = "foreignquotation" 14 15 // SaveForeignQuotationInflux stores a quotation which is not from DIA to an influx batch 16 func (datastore *DB) SaveForeignQuotationInflux(fq ForeignQuotation) error { 17 fields := map[string]interface{}{ 18 "price": fq.Price, 19 "priceYesterday": fq.PriceYesterday, 20 "source": fq.Source, 21 "volumeYesterdayUSD": fq.VolumeYesterdayUSD, 22 } 23 tags := map[string]string{ 24 "symbol": fq.Symbol, 25 "name": fq.Name, 26 } 27 pt, err := clientInfluxdb.NewPoint(influxDbForeignQuotationTable, tags, fields, fq.Time) 28 if err != nil { 29 log.Errorln("NewOptionInflux:", err) 30 } else { 31 datastore.addPoint(pt) 32 } 33 err = datastore.WriteBatchInflux() 34 if err != nil { 35 log.Errorln("Write influx batch: ", err) 36 } 37 38 return err 39 } 40 41 // GetForeignQuotationInflux returns the last quotation of @symbol before @timestamp 42 func (datastore *DB) GetForeignQuotationInflux(symbol, source string, timestamp time.Time) (ForeignQuotation, error) { 43 retval := ForeignQuotation{} 44 45 unixtime := timestamp.UnixNano() 46 q := fmt.Sprintf( 47 "SELECT price,priceYesterday,volumeYesterdayUSD,\"name\" FROM %s WHERE source='%s' and \"symbol\"='%s' and time<%d order by time desc limit 1", 48 influxDbForeignQuotationTable, 49 source, 50 symbol, 51 unixtime, 52 ) 53 res, err := queryInfluxDB(datastore.influxClient, q) 54 if err != nil { 55 fmt.Println("Error querying influx") 56 return retval, err 57 } 58 59 if len(res) > 0 && len(res[0].Series) > 0 { 60 layout := "2006-01-02T15:04:05Z" 61 vals := res[0].Series[0].Values[0] 62 63 retval.Time, err = time.Parse(layout, vals[0].(string)) 64 if err != nil { 65 log.Error(err) 66 } 67 retval.Price, err = vals[1].(json.Number).Float64() 68 if err != nil { 69 log.Error(err) 70 } 71 retval.PriceYesterday, err = vals[2].(json.Number).Float64() 72 if err != nil { 73 log.Error(err) 74 } 75 retval.VolumeYesterdayUSD, err = vals[3].(json.Number).Float64() 76 if err != nil { 77 log.Error(err) 78 } 79 80 if vals[4] != nil { 81 retval.Name = vals[4].(string) 82 } 83 retval.Source = source 84 retval.Symbol = symbol 85 86 return retval, nil 87 88 } 89 return retval, err 90 } 91 92 // GetForeignPriceYesterday returns the average price of @symbol on @source from yesterday 93 func (datastore *DB) GetForeignPriceYesterday(symbol, source string) (float64, error) { 94 95 // Get time range for yesterday in order to average the price 96 now := time.Now() 97 secondsFromYesterday := now.Hour()*60*60 + now.Minute()*60 + now.Second() 98 timeFinal := int(now.Unix()) - secondsFromYesterday - 1 99 timeInit := timeFinal - 24*60*60 100 unixtimeFinal := strconv.Itoa(timeFinal) + "000000000" 101 unixtimeInit := strconv.Itoa(timeInit) + "000000000" 102 103 // Make corresponding influx query 104 q := fmt.Sprintf("SELECT price FROM %s WHERE source='%s' and symbol='%s' and time>%s and time<%s", influxDbForeignQuotationTable, source, symbol, unixtimeInit, unixtimeFinal) 105 res, err := queryInfluxDB(datastore.influxClient, q) 106 if err != nil { 107 fmt.Println("Error querying influx") 108 return 0, err 109 } 110 111 // Simple average over all yesterday's prices 112 var price float64 113 errs := 0 114 if len(res) > 0 && len(res[0].Series) > 0 && len(res[0].Series[0].Values) > 0 { 115 numPrices := len(res[0].Series[0].Values) 116 for i := range res[0].Series[0].Values { 117 pricepoint, err := res[0].Series[0].Values[i][1].(json.Number).Float64() 118 if err != nil { 119 log.Error(err) 120 errs++ 121 } else { 122 price += pricepoint 123 } 124 125 } 126 if numPrices > errs { 127 return price / float64(numPrices-errs), nil 128 } 129 } 130 return 0, errors.New("no data available from yesterday") 131 } 132 133 // GetForeignSymbolsInflux returns a list with all symbols available for quotation from @source. 134 func (datastore *DB) GetForeignSymbolsInflux(source string) (symbols []string, err error) { 135 136 q := fmt.Sprintf("SELECT symbol,source FROM %s WHERE time>now()-7d and source='%s'", influxDbForeignQuotationTable, source) 137 res, err := queryInfluxDB(datastore.influxClient, q) 138 if err != nil { 139 fmt.Println("Error querying influx") 140 return 141 } 142 143 if len(res) > 0 && len(res[0].Series) > 0 { 144 // make unique list of symbols 145 vals := res[0].Series[0].Values 146 set := make(map[string]struct{}) 147 symsUnique := []string{} 148 for _, val := range vals { 149 if _, ok := set[val[1].(string)]; !ok { 150 symsUnique = append(symsUnique, val[1].(string)) 151 set[val[1].(string)] = struct{}{} 152 } 153 } 154 155 // fill return slice 156 for _, sym := range symsUnique { 157 symbols = append(symbols, sym) 158 } 159 } 160 return 161 }