@@ -57,10 +57,48 @@ func (u *UnaryAPI) GetAssetQuotes(symbols []string) ([]c.AssetQuote, map[string]
5757 return []c.AssetQuote {}, make (map [string ]* c.AssetQuote ), errors .New ("no symbols provided" )
5858 }
5959
60+ result , err := u .getQuotes (symbols , []string {"shortName" , "regularMarketChange" , "regularMarketChangePercent" , "regularMarketPrice" , "regularMarketPreviousClose" , "regularMarketOpen" , "regularMarketDayRange" , "regularMarketDayHigh" , "regularMarketDayLow" , "regularMarketVolume" , "postMarketChange" , "postMarketChangePercent" , "postMarketPrice" , "preMarketChange" , "preMarketChangePercent" , "preMarketPrice" , "fiftyTwoWeekHigh" , "fiftyTwoWeekLow" , "marketCap" })
61+
62+ if err != nil {
63+ return nil , nil , fmt .Errorf ("failed to get quotes: %w" , err )
64+ }
65+
66+ quotes , quotesBySymbol := transformResponseQuotes (result .QuoteResponse .Quotes )
67+
68+ return quotes , quotesBySymbol , nil
69+ }
70+
71+ // GetCurrencyRates retrieves the currency rates to convert from each currency for the given Yahoo symbols to the target currency
72+ func (u * UnaryAPI ) GetCurrencyRates (symbols []string , targetCurrency string ) (c.CurrencyRates , error ) {
73+ if targetCurrency == "" {
74+ targetCurrency = "USD"
75+ }
76+
77+ // Get currency pair symbols
78+ currencyPairSymbols , err := u .getCurrencyPairSymbols (symbols , targetCurrency )
79+ if err != nil {
80+ return c.CurrencyRates {}, fmt .Errorf ("failed to get currency pair symbols: %w" , err )
81+ }
82+
83+ if len (currencyPairSymbols ) == 0 {
84+ return c.CurrencyRates {}, nil
85+ }
86+
87+ // Get currency rates from currency pair symbols
88+ currencyRates , err := u .getCurrencyRatesFromCurrencyPairSymbols (currencyPairSymbols )
89+ if err != nil {
90+ return c.CurrencyRates {}, fmt .Errorf ("failed to get currency rates: %w" , err )
91+ }
92+
93+ return currencyRates , nil
94+ }
95+
96+ func (u * UnaryAPI ) getQuotes (symbols []string , fields []string ) (Response , error ) {
97+
6098 // Build URL with query parameters
6199 reqURL , _ := url .Parse (u .baseURL + "/v7/finance/quote" )
62100 q := reqURL .Query ()
63- q .Set ("fields" , "shortName,regularMarketChange,regularMarketChangePercent,regularMarketPrice,regularMarketPreviousClose,regularMarketOpen,regularMarketDayRange,regularMarketDayHigh,regularMarketDayLow,regularMarketVolume,postMarketChange,postMarketChangePercent,postMarketPrice,preMarketChange,preMarketChangePercent,preMarketPrice,fiftyTwoWeekHigh,fiftyTwoWeekLow,marketCap" )
101+ q .Set ("fields" , strings . Join ( fields , "," ) )
64102 q .Set ("symbols" , strings .Join (symbols , "," ))
65103
66104 // Add common Yahoo Finance query parameters
@@ -79,14 +117,14 @@ func (u *UnaryAPI) GetAssetQuotes(symbols []string) ([]c.AssetQuote, map[string]
79117 // Create request
80118 req , err := http .NewRequest ("GET" , reqURL .String (), nil )
81119 if err != nil {
82- return nil , nil , fmt .Errorf ("failed to create request: %w" , err )
120+ return Response {} , fmt .Errorf ("failed to create request: %w" , err )
83121 }
84122
85123 // Set common headers
86124 req .Header .Set ("authority" , "query1.finance.yahoo.com" )
87125 req .Header .Set ("accept" , "*/*" )
88126 req .Header .Set ("accept-language" , defaultAcceptLang )
89- req .Header .Set ("origin" , u .sessionRootURL )
127+ req .Header .Set ("origin" , u .baseURL )
90128 req .Header .Set ("user-agent" , defaultUserAgent )
91129
92130 // Add cookies if available
@@ -99,28 +137,31 @@ func (u *UnaryAPI) GetAssetQuotes(symbols []string) ([]c.AssetQuote, map[string]
99137 // Make request
100138 resp , err := u .client .Do (req )
101139 if err != nil {
102- return nil , nil , fmt .Errorf ("failed to make request: %w" , err )
140+ return Response {} , fmt .Errorf ("failed to make request: %w" , err )
103141 }
104142 defer resp .Body .Close ()
105143
106- // Handle non-200 responses
107- if resp .StatusCode != http . StatusOK {
144+ // Handle not ok responses
145+ if resp .StatusCode >= 400 {
108146 // Try to refresh session and retry once
109147 if err := u .refreshSession (); err != nil {
110- return nil , nil , fmt .Errorf ("session refresh failed: %w" , err )
148+ return Response {} , fmt .Errorf ("session refresh failed: %w" , err )
111149 }
112150
113151 // Retry request with refreshed session
114- return u .GetAssetQuotes (symbols )
152+ return u .getQuotes (symbols , fields )
153+ }
154+
155+ // Handle unexpected responses
156+ if resp .StatusCode != http .StatusOK && resp .StatusCode < 400 {
157+ return Response {}, fmt .Errorf ("unexpected response: %d" , resp .StatusCode )
115158 }
116159
117160 // Decode response
118161 var result Response
119162 if err := json .NewDecoder (resp .Body ).Decode (& result ); err != nil {
120- return nil , nil , fmt .Errorf ("failed to decode response: %w" , err )
163+ return Response {} , fmt .Errorf ("failed to decode response: %w" , err )
121164 }
122165
123- quotes , quotesBySymbol := transformResponseQuotes (result .QuoteResponse .Quotes )
124-
125- return quotes , quotesBySymbol , nil
166+ return result , nil
126167}
0 commit comments