WIP: Fix Aggregazione market Product #67
@@ -13,21 +13,28 @@ class ProductInfo(BaseModel):
|
||||
price: float = 0.0
|
||||
|
|
||||
volume_24h: float = 0.0
|
||||
currency: str = ""
|
||||
provider: str = ""
|
||||
|
Mi serviva nell'aggregate. Ma a pensarci ora quel dato era come chiave del dizionario. Vorrei giustificartelo ma adesso mi sento perso. Sono stanco e non vorrei dirti altre stronzate. Scusa, mi odierai... Mi serviva nell'aggregate. Ma a pensarci ora quel dato era come chiave del dizionario. Vorrei giustificartelo ma adesso mi sento perso. Sono stanco e non vorrei dirti altre stronzate. Scusa, mi odierai...
Guarda che non odio nessuno, sono solo più pistino di Copilot. Guarda che non odio nessuno, sono solo più pistino di Copilot.
Io chiedo solo le modifiche che sono state effettuate solo perchè le avrei fatte in un altro modo o non mi aspetto qualche cosa che è stata fatta.
|
||||
|
||||
def init(self, provider:str):
|
||||
self.provider = provider
|
||||
|
||||
@staticmethod
|
||||
def aggregate(products: dict[str, list['ProductInfo']]) -> list['ProductInfo']:
|
||||
"""
|
||||
Aggregates a list of ProductInfo by symbol.
|
||||
Aggregates a list of ProductInfo by symbol across different providers.
|
||||
Args:
|
||||
products (dict[str, list[ProductInfo]]): Map provider -> list of ProductInfo
|
||||
Returns:
|
||||
list[ProductInfo]: List of ProductInfo aggregated by symbol
|
||||
list[ProductInfo]: List of ProductInfo aggregated by symbol, combining data from all providers
|
||||
"""
|
||||
|
||||
# Costruzione mappa symbol -> lista di ProductInfo
|
||||
# Costruzione mappa symbol -> lista di ProductInfo (da tutti i provider)
|
||||
symbols_infos: dict[str, list[ProductInfo]] = {}
|
||||
for _, product_list in products.items():
|
||||
for provider_name, product_list in products.items():
|
||||
for product in product_list:
|
||||
# Assicuriamo che il provider sia impostato
|
||||
if not product.provider:
|
||||
product.provider = provider_name
|
||||
symbols_infos.setdefault(product.symbol, []).append(product)
|
||||
|
||||
# Aggregazione per ogni symbol
|
||||
@@ -37,13 +44,24 @@ class ProductInfo(BaseModel):
|
||||
|
||||
product.id = f"{symbol}_AGGREGATED"
|
||||
product.symbol = symbol
|
||||
product.currency = next(p.currency for p in product_list if p.currency)
|
||||
product.currency = next((p.currency for p in product_list if p.currency), "")
|
||||
|
||||
# Raccogliamo i provider che hanno fornito dati
|
||||
providers = [p.provider for p in product_list if p.provider]
|
||||
product.provider = ", ".join(set(providers)) if providers else "AGGREGATED"
|
||||
|
||||
volume_sum = sum(p.volume_24h for p in product_list)
|
||||
# Calcolo del volume medio
|
||||
volume_sum = sum(p.volume_24h for p in product_list if p.volume_24h > 0)
|
||||
product.volume_24h = volume_sum / len(product_list) if product_list else 0.0
|
||||
|
||||
prices = sum(p.price * p.volume_24h for p in product_list)
|
||||
product.price = (prices / volume_sum) if volume_sum > 0 else 0.0
|
||||
# Calcolo del prezzo pesato per volume (VWAP - Volume Weighted Average Price)
|
||||
if volume_sum > 0:
|
||||
prices_weighted = sum(p.price * p.volume_24h for p in product_list if p.volume_24h > 0)
|
||||
product.price = prices_weighted / volume_sum
|
||||
else:
|
||||
# Se non c'è volume, facciamo una media semplice dei prezzi
|
||||
valid_prices = [p.price for p in product_list if p.price > 0]
|
||||
product.price = sum(valid_prices) / len(valid_prices) if valid_prices else 0.0
|
||||
|
||||
aggregated_products.append(product)
|
||||
return aggregated_products
|
||||
|
||||
@@ -104,7 +104,9 @@ class MarketAPIsTool(MarketWrapper, Toolkit):
|
||||
Raises:
|
||||
Exception: If all providers fail to return results.
|
||||
"""
|
||||
all_products = self.handler.try_call_all(lambda w: w.get_products(asset_ids))
|
||||
all_products: dict[str, list[ProductInfo]] = {}
|
||||
for asset in asset_ids:
|
||||
all_products[asset] = self.handler.try_call_all(lambda w: w.get_product(asset))
|
||||
return ProductInfo.aggregate(all_products)
|
||||
|
||||
def get_historical_prices_aggregated(self, asset_id: str = "BTC", limit: int = 100) -> list[Price]:
|
||||
|
||||
@@ -139,7 +139,7 @@ class TestMarketDataAggregator:
|
||||
|
||||
info = aggregated[0]
|
||||
assert info is not None
|
||||
assert info.id == "BTC-USD_AGGREGATED"
|
||||
assert info.id == "BTC_AGGREGATED"
|
||||
assert info.symbol == "BTC"
|
||||
assert info.currency == "USD"
|
||||
assert info.price == pytest.approx(100000.0, rel=1e-3) # type: ignore
|
||||
|
||||
Reference in New Issue
Block a user
Aggiunto metodo di aggregazione singola, serve sia per un metodo GET del tool market sia per snellire la logica del secondo metodo di aggregazione quello di aggregazione multipla.
Italian comment in English codebase. Should be translated to 'Building map symbol -> list of ProductInfo (from all providers)'.
Italian comment in English codebase. Should be translated to 'Ensure that the provider is set'.
Italian comment in English codebase. Should be translated to 'Aggregation for each symbol using aggregate_single_asset'.
Italian comment in English codebase. Should be translated to 'Use aggregate_single_asset to aggregate each symbol'.
Italian comment in English codebase. Should be translated to 'If aggregate_single_asset fails (e.g., no USD when currencies differ), skip'.
Italian comment in English codebase. Should be translated to 'Currency check: if not all the same, filter only USD'.
Italian comment in English codebase. Should be translated to 'Different currencies: filter only USD'.
Italian comment in English codebase. Should be translated to 'Aggregation for each exchange'.
Italian comment in English codebase. Should be translated to 'Collect providers that have provided data'.
Italian comment in English codebase. Should be translated to 'Average volume calculation'.
Italian comment in English codebase. Should be translated to 'Volume-weighted price calculation (VWAP - Volume Weighted Average Price)'.
Italian comment in English codebase. Should be translated to 'If there is no volume, we do a simple average of prices'.
Come prima, dimenticanza da esperimento.