github.com/diadata-org/diadata@v1.4.593/internal/pkg/static-scrapers/historySAFRAvgs.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 CsafrRatesSecondaryFindByDateResponseAvg struct { 18 XMLName xml.Name `xml:"safrRatesSecondaryFindByDateResponse,omitempty" json:"safrRatesSecondaryFindByDateResponse,omitempty"` 19 CsafrRatesFindItemAvg []*CsafrRatesFindItemAvg `xml:"safrRatesFindItem,omitempty" json:"safrRatesFindItem,omitempty"` 20 } 21 22 CsafrRatesFindItemAvg struct { 23 XMLName xml.Name `xml:"safrRatesFindItem,omitempty" json:"safrRatesFindItem,omitempty"` 24 CrateOperationAvg *CrateOperationAvg `xml:"rateOperation,omitempty" json:"rateOperation,omitempty"` 25 } 26 27 CrateOperationAvg struct { 28 XMLName xml.Name `xml:"rateOperation,omitempty" json:"rateOperation,omitempty"` 29 CeffectiveDateAvg *CeffectiveDateAvg `xml:"effectiveDate,omitempty" json:"effectiveDate,omitempty"` 30 CinsertTimestampAvg *CinsertTimestampAvg `xml:"insertTimestamp,omitempty" json:"insertTimestamp,omitempty"` 31 CTenor1Avg *CTenor1Avg `xml:"tenor1,omitempty" json:"tenor1,omitempty"` 32 CTenor2Avg *CTenor2Avg `xml:"tenor2,omitempty" json:"tenor2,omitempty"` 33 CTenor3Avg *CTenor3Avg `xml:"tenor3,omitempty" json:"tenor3,omitempty"` 34 } 35 36 CeffectiveDateAvg struct { 37 XMLName xml.Name `xml:"effectiveDate,omitempty" json:"effectiveDate,omitempty"` 38 CEffDateAvg string `xml:",chardata" json:",omitempty"` 39 } 40 41 CinsertTimestampAvg struct { 42 XMLName xml.Name `xml:"insertTimestamp,omitempty" json:"insertTimestamp,omitempty"` 43 CTimestampAvg string `xml:",chardata" json:",omitempty"` 44 } 45 46 CTenor1Avg struct { 47 XMLName xml.Name `xml:"tenor1,omitempty" json:"tenor1,omitempty"` 48 CValue1Avg string `xml:",chardata" json:",omitempty"` 49 } 50 51 CTenor2Avg struct { 52 XMLName xml.Name `xml:"tenor2,omitempty" json:"tenor1,omitempty"` 53 CValue2Avg string `xml:",chardata" json:",omitempty"` 54 } 55 56 CTenor3Avg struct { 57 XMLName xml.Name `xml:"tenor3,omitempty" json:"tenor1,omitempty"` 58 CValue3Avg string `xml:",chardata" json:",omitempty"` 59 } 60 ) 61 62 // WriteHistoricSAFRAvgs makes a GET request to fetch the historic data of the SOFR 63 // average index and writes it into the redis database. 64 func WriteHistoricSAFRAvgs(ds models.Datastore) error { 65 log.Printf("Writing historic SAFR average values") 66 67 // Get rss from fed webpage 68 XMLdata, _, err := utils.GetRequest("https://apps.newyorkfed.org/api/safrate/r1") 69 70 if err != nil { 71 return err 72 } 73 74 // Decode the body 75 rss := new(CsafrRatesSecondaryFindByDateResponseAvg) 76 buffer := bytes.NewBuffer(XMLdata) 77 decoded := xml.NewDecoder(buffer) 78 err = decoded.Decode(rss) 79 80 if err != nil { 81 fmt.Println(err) 82 os.Exit(1) 83 } 84 85 // A slice containing all historic data 86 histDataSlice := rss.CsafrRatesFindItemAvg 87 numData := len(histDataSlice) 88 89 for i := 0; i < numData; i++ { 90 var rate1 float64 91 var rate2 float64 92 var rate3 float64 93 var dateTime time.Time 94 var effDate time.Time 95 96 // Convert rates from string to float64 97 rate1, err = strconv.ParseFloat(histDataSlice[i].CrateOperationAvg.CTenor1Avg.CValue1Avg, 64) 98 if err != nil { 99 fmt.Println(err) 100 } 101 rate2, err = strconv.ParseFloat(histDataSlice[i].CrateOperationAvg.CTenor2Avg.CValue2Avg, 64) 102 if err != nil { 103 fmt.Println(err) 104 } 105 106 rate3, err = strconv.ParseFloat(histDataSlice[i].CrateOperationAvg.CTenor3Avg.CValue3Avg, 64) 107 if err != nil { 108 fmt.Println(err) 109 } 110 111 // Convert time string to Time type in UTC and pass date (without daytime) 112 dateTime, err = time.Parse(time.RFC3339, histDataSlice[i].CrateOperationAvg.CinsertTimestampAvg.CTimestampAvg) 113 if err != nil { 114 log.Error("Error parsing publishing time for SOFRXXX: ", err) 115 } else { 116 dateTime = dateTime.Round(time.Second).UTC() 117 } 118 119 effDate, err = time.Parse("2006-01-02", histDataSlice[i].CrateOperationAvg.CeffectiveDateAvg.CEffDateAvg) 120 if err != nil { 121 log.Error("Error parsing effective date for SOFRXXX: ", err) 122 } 123 124 t1 := models.InterestRate{ 125 Symbol: "SOFR30", 126 Value: rate1, 127 PublicationTime: dateTime, 128 EffectiveDate: effDate, 129 Source: "FED", 130 } 131 132 t2 := models.InterestRate{ 133 Symbol: "SOFR90", 134 Value: rate2, 135 PublicationTime: dateTime, 136 EffectiveDate: effDate, 137 Source: "FED", 138 } 139 140 t3 := models.InterestRate{ 141 Symbol: "SOFR180", 142 Value: rate3, 143 PublicationTime: dateTime, 144 EffectiveDate: effDate, 145 Source: "FED", 146 } 147 148 err = ds.SetInterestRate(&t1) 149 if err != nil { 150 log.Error(err) 151 } 152 err = ds.SetInterestRate(&t2) 153 if err != nil { 154 log.Error(err) 155 } 156 err = ds.SetInterestRate(&t3) 157 if err != nil { 158 log.Error(err) 159 } 160 161 } 162 163 log.Info("Writing historic SAFR average data complete.") 164 165 return err 166 }