@@ -68,29 +68,50 @@ async def _fetch_dexscreener_price(
6868 ) -> SpotEntry | PublisherFetchError :
6969 """
7070 Query the dexscreener API and construct the SpotEntry.
71-
72- NOTE: It is really unclear at the moment how the pair is actually constructed,
73- sometimes the quote asset is in front of the base asset...
74- To be sure it works, we try both.
71+ Returns the median price from all available pairs and the total volume.
7572 """
76- pair_data = await self ._query_dexscreener (
73+ pairs_data = await self ._query_dexscreener (
7774 pair ,
7875 session ,
7976 )
80- if isinstance (pair_data , PublisherFetchError ):
77+ if isinstance (pairs_data , PublisherFetchError ):
8178 return PublisherFetchError (f"No data found for { pair } from Dexscreener" )
8279
80+ # Extract all prices and volumes
81+ prices = []
82+ total_volume = 0.0
83+ for pair_data in pairs_data :
84+ try :
85+ price = float (pair_data ["priceUsd" ])
86+ volume = float (pair_data ["volume" ]["h24" ])
87+ prices .append (price )
88+ total_volume += volume
89+ except (KeyError , ValueError , TypeError ):
90+ continue
91+
92+ if not prices :
93+ return PublisherFetchError (
94+ f"No valid price data found for { pair } from Dexscreener"
95+ )
96+
97+ # Calculate median price
98+ prices .sort ()
99+ if len (prices ) % 2 == 0 :
100+ median_price = (prices [len (prices ) // 2 - 1 ] + prices [len (prices ) // 2 ]) / 2
101+ else :
102+ median_price = prices [len (prices ) // 2 ]
103+
83104 return self ._construct (
84105 pair = pair ,
85- result = float ( pair_data [ "priceUsd" ]) ,
86- volume = float ( pair_data [ "volume" ][ "h24" ]) ,
106+ result = median_price ,
107+ volume = total_volume ,
87108 )
88109
89110 async def _query_dexscreener (
90111 self ,
91112 pair : Pair ,
92113 session : ClientSession ,
93- ) -> dict | PublisherFetchError :
114+ ) -> List [ dict ] | PublisherFetchError :
94115 url = self .format_url (pair )
95116 async with session .get (url ) as resp :
96117 if resp .status == 404 :
@@ -101,7 +122,7 @@ async def _query_dexscreener(
101122 response = await resp .json ()
102123 # NOTE: Response are sorted by highest liq, so we take the first.
103124 if response ["pairs" ] is not None and len (response ["pairs" ]) > 0 :
104- return response ["pairs" ][ 0 ] # type: ignore[no-any-return]
125+ return response ["pairs" ] # type: ignore[no-any-return]
105126 return PublisherFetchError (f"No data found for { pair .id } from Dexscreener" )
106127
107128 def format_url ( # type: ignore[override]
0 commit comments