Skip to content

Commit

Permalink
feat: include daily percentage variation
Browse files Browse the repository at this point in the history
  • Loading branch information
araujo88 committed Oct 20, 2024
1 parent 0575ce3 commit 05c2095
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 70 deletions.
54 changes: 0 additions & 54 deletions pkg/btcrate/fetch_rate.go

This file was deleted.

80 changes: 80 additions & 0 deletions pkg/coinapi/coinapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package coinapi

import (
"encoding/json"
"fmt"
"io"
"net/http"

"github.com/araujo88/bitcoin-price-bot-nostr/pkg/config"
"github.com/araujo88/bitcoin-price-bot-nostr/pkg/responses"
)

const BASE_URL = "https://rest.coinapi.io/v1/"

var API_KEY = config.GetDotEnvVariable("API_KEY")

// makeRequest handles the common operations of making an HTTP request to the CoinAPI
func makeRequest(url string) ([]byte, error) {
client := &http.Client{}
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("creating request: %w", err)
}

req.Header.Set("X-CoinAPI-Key", API_KEY)
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("executing request: %w", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

response, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("reading response: %w", err)
}

return response, nil
}

// FetchRate retrieves the current rate of Bitcoin in the specified currency
func FetchRate(currency string) (float64, error) {
url := BASE_URL + "exchangerate/BTC/" + currency
response, err := makeRequest(url)
if err != nil {
return 0, err
}

var message responses.CurrencyRate
if err := json.Unmarshal(response, &message); err != nil {
return 0, fmt.Errorf("unmarshal response: %w", err)
}

return message.Rate, nil
}

// FetchDailyVariation retrieves the daily variation in percentage of the Bitcoin price for a specified currency
func FetchDailyVariation(currency string) (float64, error) {
url := fmt.Sprintf("%sohlcv/BTC/%s/latest?period_id=1DAY&limit=1", BASE_URL, currency)
response, err := makeRequest(url)
if err != nil {
return 0, err
}

var data []responses.OHLCVData
if err := json.Unmarshal(response, &data); err != nil {
return 0, fmt.Errorf("unmarshal OHLCV data: %w", err)
}

if len(data) > 0 {
ohlcv := data[0]
variation := ((ohlcv.PriceClose - ohlcv.PriceOpen) / ohlcv.PriceOpen) * 100
return variation, nil
}

return 0, fmt.Errorf("no data found")
}
8 changes: 0 additions & 8 deletions pkg/message/message.go

This file was deleted.

44 changes: 36 additions & 8 deletions pkg/post/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"sync/atomic"
"time"

"github.com/araujo88/bitcoin-price-bot-nostr/pkg/btcrate"
"github.com/araujo88/bitcoin-price-bot-nostr/pkg/coinapi"
"github.com/araujo88/bitcoin-price-bot-nostr/pkg/config"
"github.com/araujo88/bitcoin-price-bot-nostr/pkg/relay"
"github.com/nbd-wtf/go-nostr"
Expand Down Expand Up @@ -40,14 +40,42 @@ func Post() error {
return err
}

rate_usd := 1 / btcrate.FetchRate("USD") / 0.00000001
rate_eur := 1 / btcrate.FetchRate("EUR") / 0.00000001
rate_jpy := 1 / btcrate.FetchRate("JPY") / 0.00000001
rate_gbp := 1 / btcrate.FetchRate("GBP") / 0.00000001
rate_brl := 1 / btcrate.FetchRate("BRL") / 0.00000001
rate_usd, err := coinapi.FetchRate("USD")
if err != nil {
return errors.New("error fetching rate for USD")
}
rate_eur, err := coinapi.FetchRate("EUR")
if err != nil {
return errors.New("error fetching rate for EUR")
}
rate_brl, err := coinapi.FetchRate("BRL")
if err != nil {
return errors.New("error fetching rate for BRL")
}

daily_variation_usd, err := coinapi.FetchDailyVariation("USD")
if err != nil {
return errors.New("error fetching daily vartion for USD")
}

daily_variation_eur, err := coinapi.FetchDailyVariation("EUR")
if err != nil {
return errors.New("error fetching daily vartion for EUR")
}

daily_variation_brl, err := coinapi.FetchDailyVariation("BRL")
if err != nil {
return errors.New("error fetching daily vartion for BRL")
}

content := fmt.Sprintf(`1 BTC = %.0f USD (%.2f %%)\n
1 BTC = %0.f EUR (%.2f %%)\n
1 BTC = %0.f BRL (%.2f %%)\n`,
rate_usd, daily_variation_usd,
rate_eur, daily_variation_eur,
rate_brl, daily_variation_brl)

price_string := fmt.Sprintf("1 USD = %.0f sats\n1 EUR = %0.f sats\n1 JPY = %0.f sats\n1 GBP = %0.f sats\n1 BRL = %0.f sats", rate_usd, rate_eur, rate_jpy, rate_gbp, rate_brl)
ev.Content = price_string
ev.Content = content

ev.CreatedAt = time.Now()
ev.Kind = nostr.KindTextNote
Expand Down
21 changes: 21 additions & 0 deletions pkg/responses/resposes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package responses

type CurrencyRate struct {
Time string `json:"time"`
AssetIdBase string `json:"asset_id_base"`
AssetIdQuote string `json:"asset_id_quote"`
Rate float64 `json:"rate"`
}

type OHLCVData struct {
TimePeriodStart string `json:"time_period_start"`
TimePeriodEnd string `json:"time_period_end"`
TimeOpen string `json:"time_open"`
TimeClose string `json:"time_close"`
PriceOpen float64 `json:"price_open"`
PriceHigh float64 `json:"price_high"`
PriceLow float64 `json:"price_low"`
PriceClose float64 `json:"price_close"`
VolumeTraded float64 `json:"volume_traded"`
TradesCount int `json:"trades_count"`
}

0 comments on commit 05c2095

Please sign in to comment.