github.com/diadata-org/diadata@v1.4.593/internal/pkg/static-scrapers/historySAFR.go (about) 1 package staticscrapers 2 3 import ( 4 "bytes" 5 "encoding/xml" 6 "fmt" 7 "os" 8 "strconv" 9 "time" 10 11 models "github.com/diadata-org/diadata/pkg/model" 12 utils "github.com/diadata-org/diadata/pkg/utils" 13 log "github.com/sirupsen/logrus" 14 ) 15 16 type ( 17 CsafrRatesSecondaryFindByDateResponseInd struct { 18 XMLName xml.Name `xml:"safrRatesSecondaryFindByDateResponse,omitempty" json:"safrRatesSecondaryFindByDateResponse,omitempty"` 19 CsafrRatesFindItemInd []*CsafrRatesFindItemInd `xml:"safrRatesFindItem,omitempty" json:"safrRatesFindItem,omitempty"` 20 } 21 22 CsafrRatesFindItemInd struct { 23 XMLName xml.Name `xml:"safrRatesFindItem,omitempty" json:"safrRatesFindItem,omitempty"` 24 CrateOperationInd *CrateOperationInd `xml:"rateOperation,omitempty" json:"rateOperation,omitempty"` 25 } 26 27 CrateOperationInd struct { 28 XMLName xml.Name `xml:"rateOperation,omitempty" json:"rateOperation,omitempty"` 29 CeffectiveDateInd *CeffectiveDateInd `xml:"effectiveDate,omitempty" json:"effectiveDate,omitempty"` 30 CinsertTimestampInd *CinsertTimestampInd `xml:"insertTimestamp,omitempty" json:"insertTimestamp,omitempty"` 31 CrateIndexInd *CrateIndexInd `xml:"rateIndex,omitempty" json:"rateIndex,omitempty"` 32 CrateTypeInd *CrateTypeInd `xml:"rateType,omitempty" json:"rateType,omitempty"` 33 } 34 35 CeffectiveDateInd struct { 36 XMLName xml.Name `xml:"effectiveDate,omitempty" json:"effectiveDate,omitempty"` 37 CEffDateInd string `xml:",chardata" json:",omitempty"` 38 } 39 40 CinsertTimestampInd struct { 41 XMLName xml.Name `xml:"insertTimestamp,omitempty" json:"insertTimestamp,omitempty"` 42 CTimestampInd string `xml:",chardata" json:",omitempty"` 43 } 44 45 CrateIndexInd struct { 46 XMLName xml.Name `xml:"rateIndex,omitempty" json:"rateIndex,omitempty"` 47 CValueInd string `xml:",chardata" json:",omitempty"` 48 } 49 50 CrateTypeInd struct { 51 XMLName xml.Name `xml:"rateType,omitempty" json:"rateType,omitempty"` 52 CTypeInd string `xml:",chardata" json:",omitempty"` 53 } 54 ) 55 56 // WriteHistoricSAFR makes a GET request to fetch the historic data of the SOFR 57 // average index and writes it into the redis database. 58 func WriteHistoricSAFR(ds models.Datastore) error { 59 log.Printf("Writing historic SAFR values") 60 61 // Get rss from fed webpage 62 XMLdata, _, err := utils.GetRequest("https://apps.newyorkfed.org/api/safrate/r1") 63 64 if err != nil { 65 return err 66 } 67 68 // Decode the body 69 rss := new(CsafrRatesSecondaryFindByDateResponseInd) 70 buffer := bytes.NewBuffer(XMLdata) 71 decoded := xml.NewDecoder(buffer) 72 err = decoded.Decode(rss) 73 74 if err != nil { 75 fmt.Println(err) 76 os.Exit(1) 77 } 78 79 // A slice containing all historic data 80 histDataSlice := rss.CsafrRatesFindItemInd 81 numData := len(histDataSlice) 82 83 for i := 0; i < numData; i++ { 84 var rate float64 85 var dateTime time.Time 86 var effDate time.Time 87 88 // Convert interest rate from string to float64 89 rate, err = strconv.ParseFloat(histDataSlice[i].CrateOperationInd.CrateIndexInd.CValueInd, 64) 90 if err != nil { 91 fmt.Println(err) 92 } 93 94 // Convert time string to Time type in UTC and pass date (without daytime) 95 dateTime, err = time.Parse(time.RFC3339, histDataSlice[i].CrateOperationInd.CinsertTimestampInd.CTimestampInd) 96 if err != nil { 97 log.Error("error parsing publishing time of historic SAFR: ", err) 98 } else { 99 dateTime = dateTime.Round(time.Second).UTC() 100 } 101 102 effDate, err = time.Parse("2006-01-02", histDataSlice[i].CrateOperationInd.CeffectiveDateInd.CEffDateInd) 103 if err != nil { 104 log.Error("error parsing effective date of historic SAFR: ", err) 105 } 106 107 t := models.InterestRate{ 108 Symbol: "SAFR", 109 Value: rate, 110 PublicationTime: dateTime, 111 EffectiveDate: effDate, 112 Source: "FED", 113 } 114 115 err = ds.SetInterestRate(&t) 116 if err != nil { 117 log.Error(err) 118 } 119 120 } 121 122 log.Info("Writing historic SAFR data complete.") 123 124 return err 125 }