|
|
@@ -52,30 +52,41 @@ def analyze_markets(prices: typing.Sequence[market.RawPrice], date: datetime.dat
|
|
|
continue
|
|
|
markets[price['MaterialTicker']].append(price)
|
|
|
|
|
|
- markets_with_trades = ranking = ic1_lowest = ic1_zero = gap = 0
|
|
|
+ markets_with_trades = total_rank = ic1_lowest = ic1_zero = gap = 0
|
|
|
for mat, mat_prices in markets.items():
|
|
|
- mat_prices.sort(key=lambda p: (p['Traded7D'] or 0))
|
|
|
- if mat_prices[-1]['Traded7D'] == None:
|
|
|
+ # find IC1's Traded7D rank among the CXes
|
|
|
+ # group CXes by Traded7D first in case of ties
|
|
|
+ rankings: dict[int, list[str]] = collections.defaultdict(list)
|
|
|
+ for price in mat_prices:
|
|
|
+ rankings[price['Traded7D'] or 0].append(price['ExchangeCode'])
|
|
|
+ if len(rankings) == 1 and 0 in rankings: # no markets had any trades
|
|
|
continue
|
|
|
- markets_with_trades += 1
|
|
|
- for index, price in enumerate(mat_prices):
|
|
|
- if price['ExchangeCode'] == 'IC1':
|
|
|
+ sorted_markets = sorted(rankings.items(), key=lambda item: item[0])
|
|
|
+ rank = 0
|
|
|
+ for _, cxes in sorted_markets:
|
|
|
+ if 'IC1' in cxes:
|
|
|
break
|
|
|
+ rank += len(cxes)
|
|
|
else:
|
|
|
raise AssertionError('IC1 not found for ' + mat)
|
|
|
- ranking += index
|
|
|
- if index == 0:
|
|
|
+ markets_with_trades += 1
|
|
|
+ total_rank += rank
|
|
|
+
|
|
|
+ if rank == 0:
|
|
|
ic1_lowest += 1
|
|
|
- ic1_traded = mat_prices[0]['Traded7D'] or 0
|
|
|
- lowest_traded = mat_prices[1]['Traded7D'] or 0
|
|
|
+ ic1_traded = sorted_markets[0][0]
|
|
|
+ if len(sorted_markets[0][1]) > 1: # another market is tied for last with us
|
|
|
+ lowest_traded = ic1_traded
|
|
|
+ else:
|
|
|
+ lowest_traded = sorted_markets[1][0]
|
|
|
if lowest_traded > 0:
|
|
|
if ic1_traded == 0:
|
|
|
ic1_zero += 1
|
|
|
gap += (lowest_traded - ic1_traded) / lowest_traded
|
|
|
- print(f'{markets_with_trades} markets with trades, IC1 ranking {ranking}, lowest in {ic1_lowest}, zero in {ic1_zero}, gap {gap:.2f}')
|
|
|
+ print(f'{markets_with_trades} markets with trades, IC1 total rank {total_rank}, lowest in {ic1_lowest}, zero in {ic1_zero}, gap {gap:.2f}')
|
|
|
return {
|
|
|
'date': date.isoformat(),
|
|
|
- 'ranking': ranking / markets_with_trades,
|
|
|
+ 'ranking': total_rank / markets_with_trades,
|
|
|
'ic1_lowest': ic1_lowest / markets_with_trades * 100,
|
|
|
'ic1_zero': ic1_zero,
|
|
|
'gap': gap / markets_with_trades * 100,
|