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  }