feat: signal abstraction layer + sizer + HS300 universe + PnL/IC reports

This commit is contained in:
Yuxuan Yan
2026-06-07 09:44:33 +08:00
parent 085e51abf1
commit da01312292
20 changed files with 610 additions and 23 deletions
+40
View File
@@ -0,0 +1,40 @@
"""Map signal values to discrete position actions."""
from dataclasses import dataclass
@dataclass
class PositionAction:
"""A target action for a single stock on a single bar."""
action: str # "buy", "sell", or "hold"
size_pct: float = 0.0 # target portfolio fraction for buys
class ThresholdBuilder:
"""Open on strong positive signal, close on strong negative signal."""
def __init__(
self,
buy_threshold: float = 0.02,
sell_threshold: float = -0.02,
size_pct: float = 0.95,
):
self.buy_threshold = buy_threshold
self.sell_threshold = sell_threshold
self.size_pct = size_pct
def build(self, signal_value: float, in_position: bool) -> PositionAction:
"""Decide what to do given the current signal and position state.
Args:
signal_value: Latest signal value for the stock.
in_position: Whether the portfolio currently holds the stock.
Returns:
The action to take ("buy", "sell", or "hold").
"""
if not in_position and signal_value >= self.buy_threshold:
return PositionAction("buy", self.size_pct)
if in_position and signal_value <= self.sell_threshold:
return PositionAction("sell", 0.0)
return PositionAction("hold", 0.0)