feat(EXEC-001A): add named strategy templates
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
from .base import BaseStrategy, StrategyConfig
|
||||
from .engine import StrategySelectionEngine
|
||||
from .laddered_put import LadderedPutStrategy, LadderSpec
|
||||
from .lease import LeaseAnalysisSpec, LeaseStrategy
|
||||
from .protective_put import ProtectivePutSpec, ProtectivePutStrategy
|
||||
@@ -15,3 +14,11 @@ __all__ = [
|
||||
"LeaseStrategy",
|
||||
"StrategySelectionEngine",
|
||||
]
|
||||
|
||||
|
||||
def __getattr__(name: str):
|
||||
if name == "StrategySelectionEngine":
|
||||
from .engine import StrategySelectionEngine
|
||||
|
||||
return StrategySelectionEngine
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
@@ -9,10 +9,9 @@ from app.core.pricing.black_scholes import (
|
||||
DEFAULT_VOLATILITY,
|
||||
)
|
||||
from app.models.portfolio import LombardPortfolio
|
||||
from app.services.strategy_templates import StrategyTemplateService
|
||||
from app.strategies.base import BaseStrategy, StrategyConfig
|
||||
from app.strategies.laddered_put import LadderedPutStrategy, LadderSpec
|
||||
from app.strategies.lease import LeaseStrategy
|
||||
from app.strategies.protective_put import ProtectivePutSpec, ProtectivePutStrategy
|
||||
|
||||
RiskProfile = Literal["conservative", "balanced", "cost_sensitive"]
|
||||
|
||||
@@ -34,6 +33,7 @@ class StrategySelectionEngine:
|
||||
spot_price: float = RESEARCH_GLD_SPOT
|
||||
volatility: float = RESEARCH_VOLATILITY
|
||||
risk_free_rate: float = RESEARCH_RISK_FREE_RATE
|
||||
template_service: StrategyTemplateService | None = None
|
||||
|
||||
def _config(self) -> StrategyConfig:
|
||||
portfolio = LombardPortfolio(
|
||||
@@ -52,30 +52,12 @@ class StrategySelectionEngine:
|
||||
|
||||
def _strategies(self) -> list[BaseStrategy]:
|
||||
config = self._config()
|
||||
return [
|
||||
ProtectivePutStrategy(config, ProtectivePutSpec(label="ATM", strike_pct=1.0, months=12)),
|
||||
ProtectivePutStrategy(config, ProtectivePutSpec(label="OTM_95", strike_pct=0.95, months=12)),
|
||||
ProtectivePutStrategy(config, ProtectivePutSpec(label="OTM_90", strike_pct=0.90, months=12)),
|
||||
LadderedPutStrategy(
|
||||
config,
|
||||
LadderSpec(
|
||||
label="50_50_ATM_OTM95",
|
||||
weights=(0.5, 0.5),
|
||||
strike_pcts=(1.0, 0.95),
|
||||
months=12,
|
||||
),
|
||||
),
|
||||
LadderedPutStrategy(
|
||||
config,
|
||||
LadderSpec(
|
||||
label="33_33_33_ATM_OTM95_OTM90",
|
||||
weights=(1 / 3, 1 / 3, 1 / 3),
|
||||
strike_pcts=(1.0, 0.95, 0.90),
|
||||
months=12,
|
||||
),
|
||||
),
|
||||
LeaseStrategy(config),
|
||||
template_service = self.template_service or StrategyTemplateService()
|
||||
template_strategies = [
|
||||
template_service.build_strategy_from_template(config, template)
|
||||
for template in template_service.list_active_templates("GLD")
|
||||
]
|
||||
return [*template_strategies, LeaseStrategy(config)]
|
||||
|
||||
def compare_all_strategies(self) -> list[dict]:
|
||||
comparisons: list[dict] = []
|
||||
@@ -149,6 +131,7 @@ class StrategySelectionEngine:
|
||||
spot_price=self.spot_price,
|
||||
volatility=volatility,
|
||||
risk_free_rate=self.risk_free_rate,
|
||||
template_service=self.template_service,
|
||||
)
|
||||
recommendation = engine.recommend("balanced")
|
||||
results["volatility"].append(
|
||||
@@ -169,6 +152,7 @@ class StrategySelectionEngine:
|
||||
spot_price=spot_price,
|
||||
volatility=DEFAULT_VOLATILITY,
|
||||
risk_free_rate=DEFAULT_RISK_FREE_RATE,
|
||||
template_service=self.template_service,
|
||||
)
|
||||
recommendation = engine.recommend("balanced")
|
||||
results["spot_price"].append(
|
||||
|
||||
Reference in New Issue
Block a user