"""Fixed-portfolio concentration diagnostics and purged chronological fits.""" import numpy as np import pandas as pd def gross_community_hhi(partition,weights): if not weights or not set(weights)<=set(partition):raise ValueError('All portfolio issuers must have memberships') gross=sum(abs(float(w)) for w in weights.values()) if not np.isfinite(gross) or gross<=0:raise ValueError('Require finite nonzero gross weights') groups={} for issuer,weight in weights.items(): group=partition[issuer] groups[group]=groups.get(group,0.)+abs(float(weight))/gross return float(sum(share**2 for share in groups.values())) def diversification_loss(returns): """Normalized realized variance, with no missing-asset substitution.""" if len(returns)<2 or not len(returns.columns) or not returns.columns.is_unique: raise ValueError('Require multiple complete returns and unique portfolio columns') values=returns.to_numpy(dtype=float) if not np.isfinite(values).all():return np.nan denominator=float(values.std(axis=0,ddof=0).mean())**2 if denominator<=0:return np.nan ratio=float(values.mean(axis=1).var(ddof=0))/denominator if ratio>1.+1e-9:raise ValueError('Normalized variance exceeded its mathematical bound') return float(np.clip(ratio,0.,1.)) def purged_training_mask(dates,target_end,train_end): end=pd.to_datetime(target_end).reindex(dates) if not dates.is_unique or not dates.is_monotonic_increasing or (end1)).any():raise ValueError('Target must be bounded normalized variance') mean=x.mean();scale=x.std(ddof=0).replace(0.,1.) design=np.column_stack([np.ones(len(x)),((x-mean)/scale).to_numpy()]) penalty=np.eye(design.shape[1])*alpha;penalty[0,0]=0. coefficient=np.linalg.solve(design.T@design+penalty,design.T@y) scored=np.column_stack([np.ones(int(valid.sum())),((features.loc[valid]-mean)/scale).to_numpy()]) prediction.loc[valid]=np.clip(scored@coefficient,0.,1.) model=dict(state='fitted',training_rows=int(training.sum()),training_dates=[str(d.date()) for d in x.index], columns=list(features),mean=mean.to_dict(),scale=scale.to_dict(),coefficient=coefficient.tolist(),alpha=alpha, objective='sum squared training residuals plus alpha times squared feature coefficients; intercept unpenalized') return model,prediction def paired_error_improvement(target,candidate,baseline,block=4,repeats=1000,seed=20261105): if not target.index.equals(candidate.index) or not target.index.equals(baseline.index): raise ValueError('Keep the complete original scheduled test calendar') losses=(baseline-target)**2-(candidate-target)**2 valid=np.isfinite(losses.to_numpy());values=losses.to_numpy();n=len(values) if not valid.any():return dict(scheduled_observations=n,common_observations=0,mean_improvement=None,interval_95=None,usable_resamples=0) rng=np.random.default_rng(seed);draws=[] for _ in range(repeats): starts=rng.integers(0,n,size=(n+block-1)//block) sample=np.concatenate([(np.arange(block)+start)%n for start in starts])[:n] usable=values[sample][valid[sample]] if len(usable):draws.append(float(usable.mean())) return dict(scheduled_observations=n,common_observations=int(valid.sum()),mean_improvement=float(values[valid].mean()), interval_95=np.quantile(draws,[.025,.975]).tolist() if draws else None,usable_resamples=len(draws),block_observations=block)