Share point-in-time signals and a cash-funded order ledger across backtests and trading. Correct eligibility, missing-price fills, quality factors, regime inputs, warmup windows, and cash-injection accounting. Add reproducible registered-strategy comparisons and paired forward candidates with a 20% resize band. Validation: 125 Python tests, 23 web tests, TypeScript/Vite build, 87 strategy causality checks, and real-data target/order/equity parity for 10 strategies.
21 lines
910 B
Python
21 lines
910 B
Python
import pandas as pd
|
|
from strategies.base import StockStrategy, mask_scores
|
|
|
|
|
|
class BuyAndHoldStrategy(StockStrategy):
|
|
def __init__(self, asset: str | None = None):
|
|
self.asset = asset
|
|
|
|
def generate_signals(self, data, eligible=None):
|
|
if self.asset is not None:
|
|
if self.asset not in data:
|
|
raise ValueError(f"Missing buy-and-hold benchmark: {self.asset}")
|
|
weights = pd.DataFrame(0.0, index=data.index, columns=data.columns)
|
|
weights[self.asset] = data[self.asset].notna().astype(float)
|
|
else:
|
|
# A fixed initial basket; new listings never enter retrospectively.
|
|
first = data.iloc[0]
|
|
values = data.ffill().div(first).where(first.notna(), 0.0).fillna(0.0)
|
|
weights = values.div(values.sum(axis=1).replace(0, float('nan')), axis=0).fillna(0.0)
|
|
return weights.shift(1).fillna(0.0)
|