"""Standalone daily-score functions; venue gates and deduplication are documented separately.""" import math import statistics as st DAY=86400 def clip(x):return max(0,min(1,x)) def calculate(candles,btc,cutoff): by={int(k[0])//1000:k for k in candles if int(k[0])//1000=50000 for r in bars[-7:])/7 parts=dict(turnover=10*clip(math.log10(med/50000)/2),drawdown=10*clip(1-dd/.7),trend=10*(.5*(p>sma)+.5*(sma>sma_all)),relative_btc=10*clip(.5+(r7-btcret)/.6),participation=10*active) penalty=min(1,max(0,p/sma-1-.2)/.5) weights=dict(turnover=.30,drawdown=.25,trend=.20,relative_btc=.15,participation=.10) score=max(0,sum(parts[k]*v for k,v in weights.items())-penalty) return dict(raw_score=score,components=parts,weights=weights,extension_penalty=penalty,close=p,sma7=sma,sma_window=sma_all,return7=r7,btc_return7=btcret,excess_btc7=r7-btcret,drawdown=dd,annualized_volatility=vol,median_quote7=med,active_day_share=active,window_days=len(bars),score_window_days=7,first_candle=series[0],bars=bars,stance='Trend supported; monitor entry conditions' if p>sma and r7>0 else 'Recovery watch; wait for trend repair'),None