1- package monitorYahoo
1+ package monitorPriceYahoo
22
33import (
44 "context"
88 "time"
99
1010 c "github.com/achannarasappa/ticker/v4/internal/common"
11- poller "github.com/achannarasappa/ticker/v4/internal/monitor/yahoo/poller"
11+ poller "github.com/achannarasappa/ticker/v4/internal/monitor/yahoo/monitor-price/ poller"
1212 unary "github.com/achannarasappa/ticker/v4/internal/monitor/yahoo/unary"
1313)
1414
@@ -18,24 +18,23 @@ type MonitorYahoo struct {
1818 poller * poller.Poller
1919 unary * unary.UnaryAPI
2020 input input
21- productIds [] string // Yahoo APIs refer to trading pairs as Product IDs which symbols ticker accepts with a -USD suffix
22- productIdsPolling [ ]string
21+ symbols [] string
22+ symbolToCurrency map [ string ]string // Map of symbols to currency
2323 assetQuotesCache []c.AssetQuote // Asset quotes for all assets retrieved at start or on symbol change
2424 assetQuotesCacheLookup map [string ]* c.AssetQuote // Asset quotes for all assets retrieved at least once (symbol change does not remove symbols)
2525 chanPollUpdateAssetQuote chan c.MessageUpdate [c.AssetQuote ]
26-
27- chanError chan error
28- mu sync.RWMutex
29- ctx context.Context
30- cancel context.CancelFunc
31- isStarted bool
32- chanUpdateAssetQuote chan c.MessageUpdate [c.AssetQuote ]
26+ chanError chan error
27+ mu sync.RWMutex
28+ ctx context.Context
29+ cancel context.CancelFunc
30+ isStarted bool
31+ chanUpdateAssetQuote chan c.MessageUpdate [c.AssetQuote ]
3332}
3433
3534// input represents user input for the Yahoo monitor with any transformation
3635type input struct {
37- productIds []string
38- productIdsLookup map [string ]bool
36+ symbols []string
37+ symbolsLookup map [string ]bool
3938}
4039
4140// Config contains the required configuration for the Yahoo monitor
@@ -65,6 +64,7 @@ func NewMonitorYahoo(config Config, opts ...Option) *MonitorYahoo {
6564
6665 monitor := & MonitorYahoo {
6766 assetQuotesCacheLookup : make (map [string ]* c.AssetQuote ),
67+ symbolToCurrency : make (map [string ]string ),
6868 assetQuotesCache : make ([]c.AssetQuote , 0 ),
6969 chanPollUpdateAssetQuote : make (chan c.MessageUpdate [c.AssetQuote ]),
7070 chanError : config .ChanError ,
@@ -115,32 +115,38 @@ func (m *MonitorYahoo) GetAssetQuotes(ignoreCache ...bool) ([]c.AssetQuote, erro
115115}
116116
117117// SetSymbols sets the symbols to monitor
118- func (m * MonitorYahoo ) SetSymbols (productIds []string , nonce int ) error {
118+ func (m * MonitorYahoo ) SetSymbols (symbols []string , nonce int ) error {
119119
120120 var err error
121121
122122 m .mu .Lock ()
123123
124- // Deduplicate productIds since input may have duplicates
125- slices .Sort (productIds )
126- m .productIds = slices .Compact (productIds )
127- m .productIdsPolling = m .productIds
128- m .input .productIds = productIds
129- m .input .productIdsLookup = make (map [string ]bool )
130- for _ , productId := range productIds {
131- m .input .productIdsLookup [productId ] = true
124+ // Deduplicate symbols since input may have duplicates
125+ slices .Sort (symbols )
126+ m .symbols = slices .Compact (symbols )
127+ m .input .symbols = symbols
128+ m .input .symbolsLookup = make (map [string ]bool )
129+ for _ , symbol := range symbols {
130+ m .input .symbolsLookup [symbol ] = true
132131 }
133132
134133 m .mu .Unlock ()
135134
135+ // Check for symbols which don't have a known currency and retrieve the currency for those symbols
136+ // TODO: conditionally bypass if currency conversion is not enabled
137+ // err = m.getCurrencyForEachSymbolAndUpdateCurrencyMap()
138+ // if err != nil {
139+ // return err
140+ // }
141+
136142 // Since the symbols have changed, make a synchronous call to get price quotes for the new symbols
137143 _ , err = m .getAssetQuotesAndReplaceCache ()
138144 if err != nil {
139145 return err
140146 }
141147
142148 // Set the symbols to monitor on the poller
143- m .poller .SetSymbols (m .productIdsPolling , nonce )
149+ m .poller .SetSymbols (m .symbols , nonce )
144150
145151 return nil
146152
@@ -254,7 +260,7 @@ func (m *MonitorYahoo) handleUpdates() {
254260func (m * MonitorYahoo ) getAssetQuotesAndReplaceCache () ([]c.AssetQuote , error ) {
255261
256262 // Make a synchronous call to get price quotes
257- assetQuotes , assetQuotesByProductId , err := m .unaryAPI .GetAssetQuotes (m .productIds )
263+ assetQuotes , assetQuotesByProductId , err := m .unaryAPI .GetAssetQuotes (m .symbols )
258264 if err != nil {
259265 return []c.AssetQuote {}, err
260266 }
@@ -268,3 +274,47 @@ func (m *MonitorYahoo) getAssetQuotesAndReplaceCache() ([]c.AssetQuote, error) {
268274
269275 return m .assetQuotesCache , nil
270276}
277+
278+ func (m * MonitorYahoo ) getCurrencyForEachSymbolAndUpdateCurrencyMap () error {
279+ // No need to process if no symbols are provided
280+ if len (m .symbols ) == 0 {
281+ return nil
282+ }
283+
284+ symbolsWithoutCurrency := make ([]string , 0 )
285+
286+ // Check if symbols already have a currency mapping
287+ for _ , symbol := range m .symbols {
288+ if _ , exists := m .symbolToCurrency [symbol ]; ! exists {
289+ symbolsWithoutCurrency = append (symbolsWithoutCurrency , symbol )
290+ }
291+ }
292+
293+ // Get currency information for each symbol
294+ symbolToCurrency , err := m .unaryAPI .GetCurrencyMap (symbolsWithoutCurrency )
295+ if err != nil {
296+ return fmt .Errorf ("failed to get currency information: %w" , err )
297+ }
298+
299+ m .mu .Lock ()
300+ defer m .mu .Unlock ()
301+
302+ // Update currency information in the existing asset quotes cache
303+ for symbol , currency := range symbolToCurrency {
304+ m .symbolToCurrency [symbol ] = currency .FromCurrency
305+ }
306+
307+ return nil
308+ }
309+
310+ // GetCurrencyRates accepts an array of ISO 4217 currency codes and a target ISO 4217 currency code and returns a conversion rate for each of the input currencies to the target currency
311+ func (m * MonitorYahoo ) GetCurrencyRates (inputCurrencies []string , targetCurrency string ) (c.CurrencyRates , error ) {
312+
313+ // currencyRates, err := m.unaryAPI.GetCurrencyRates(inputCurrencies, targetCurrency)
314+ // if err != nil {
315+ // return nil, fmt.Errorf("failed to get currency rates: %w", err)
316+ // }
317+
318+ // return currencyRates, nil
319+ return nil , nil
320+ }
0 commit comments