Skip to content

Strategies

Base

midas.strategies.base

Abstract strategy interface.

Strategy

Bases: ABC

Base class for all signal strategies.

Strategies are stateless and ticker-agnostic. They receive price history and return a conviction score.

Source code in src/midas/strategies/base.py
class Strategy(ABC):
    """Base class for all signal strategies.

    Strategies are stateless and ticker-agnostic. They receive price history
    and return a conviction score.
    """

    @abstractmethod
    def score(
        self,
        price_history: pd.Series,
        **kwargs: object,
    ) -> float | None:
        """Return conviction score.

        Positive = bullish, negative = bearish, 0 = neutral, None = abstain.
        Typically in [-1, +1].
        """

    @property
    def tier(self) -> StrategyTier:
        """Strategy tier — override in subclass if not CONVICTION."""
        return StrategyTier.CONVICTION

    @staticmethod
    def _clamp(value: float, lo: float = 0.0, hi: float = 1.0) -> float:
        """Clamp *value* into [lo, hi]."""
        return max(lo, min(hi, value))

    def generate_intents(
        self,
        ticker: str,
        price_history: pd.Series,
        **kwargs: object,
    ) -> list[MechanicalIntent]:
        """Return mechanical order intents. Override for MECHANICAL strategies."""
        return []

    @property
    def name(self) -> str:
        """Human-readable strategy name."""
        return type(self).__name__

    @property
    @abstractmethod
    def suitability(self) -> list[AssetSuitability]:
        """Asset classes this strategy is appropriate for."""

    @property
    @abstractmethod
    def description(self) -> str:
        """One-line description of the strategy logic."""

description abstractmethod property

One-line description of the strategy logic.

name property

Human-readable strategy name.

suitability abstractmethod property

Asset classes this strategy is appropriate for.

tier property

Strategy tier — override in subclass if not CONVICTION.

generate_intents(ticker, price_history, **kwargs)

Return mechanical order intents. Override for MECHANICAL strategies.

Source code in src/midas/strategies/base.py
def generate_intents(
    self,
    ticker: str,
    price_history: pd.Series,
    **kwargs: object,
) -> list[MechanicalIntent]:
    """Return mechanical order intents. Override for MECHANICAL strategies."""
    return []

score(price_history, **kwargs) abstractmethod

Return conviction score.

Positive = bullish, negative = bearish, 0 = neutral, None = abstain. Typically in [-1, +1].

Source code in src/midas/strategies/base.py
@abstractmethod
def score(
    self,
    price_history: pd.Series,
    **kwargs: object,
) -> float | None:
    """Return conviction score.

    Positive = bullish, negative = bearish, 0 = neutral, None = abstain.
    Typically in [-1, +1].
    """

Mean Reversion

midas.strategies.mean_reversion

Mean reversion strategy: buy when price drops below moving average.

Momentum

midas.strategies.momentum

Momentum strategy: buy when price crosses above moving average.

Profit Taking

midas.strategies.profit_taking

Profit taking strategy: sell when unrealized gains exceed threshold.

Stop Loss

midas.strategies.stop_loss

Stop loss strategy: sell when unrealized loss exceeds threshold.

Trailing Stop

midas.strategies.trailing_stop

Trailing stop strategy: sell when price falls from high-water mark.

RSI Oversold

midas.strategies.rsi_oversold

RSI oversold strategy: buy when RSI drops below threshold.

RSI Overbought

midas.strategies.rsi_overbought

RSI overbought strategy: sell when RSI exceeds threshold.

Bollinger Band

midas.strategies.bollinger_band

Bollinger Band strategy: buy when price touches lower band.

MACD Crossover

midas.strategies.macd_crossover

MACD crossover strategy: buy when MACD line crosses above signal line.

Gap Down Recovery

midas.strategies.gap_down_recovery

Gap down recovery strategy: buy when price gaps down then recovers.

VWAP Reversion

midas.strategies.vwap_reversion

VWAP reversion strategy: buy below average price, sell above.

Note: Without volume data, this uses a simple moving average as a proxy for VWAP. With volume data available via the provider, this could be extended to use true volume-weighted average price.

Moving Average Crossover

midas.strategies.ma_crossover

Moving average crossover: buy on golden cross, sell on death cross.

Dollar Cost Averaging

midas.strategies.dca

Dollar-cost averaging strategy: buy on a regular cadence.