quant_test / backtest /portfolio_construction.py
lucky-loster's picture
Upload folder using huggingface_hub
590a501 verified
Raw
History Blame Contribute Delete
1.31 kB
"""Portfolio construction from model scores."""
from __future__ import annotations
import pandas as pd
def top_k_equal_weight(scores: pd.DataFrame, k: int = 30) -> pd.DataFrame:
"""
Build equal-weight long-only portfolio from cross-sectional scores.
Input: MultiIndex (instrument, datetime) with score column or Series.
"""
if isinstance(scores, pd.Series):
scores = scores.to_frame("score")
weights = []
for dt, group in scores.groupby(level="datetime"):
top = group.nlargest(k, "score")
w = pd.Series(1.0 / len(top), index=top.index)
weights.append(w)
return pd.concat(weights).to_frame("weight")
def long_short_quantile(scores: pd.DataFrame, n_groups: int = 5) -> pd.DataFrame:
weights = []
for dt, group in scores.groupby(level="datetime"):
group = group.copy()
group["group"] = pd.qcut(group["score"].rank(method="first"), n_groups, labels=False)
long = group[group["group"] == n_groups - 1]
short = group[group["group"] == 0]
w = pd.Series(0.0, index=group.index)
if len(long):
w.loc[long.index] = 0.5 / len(long)
if len(short):
w.loc[short.index] = -0.5 / len(short)
weights.append(w.to_frame("weight"))
return pd.concat(weights)