Skip to content
Back to skills

Risk Stop Loss

ASecurity

'"Implements stop loss strategies for risk management for risk management

  • 4 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added June 12, 2026
documentationpythongoapidocumentation

Works with

  • api

Security analysis

A100/100

Scanned June 12, 2026

npx -y skills add paulpas/agent-skill-router --skill risk-stop-loss --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Risk Stop Loss?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Risk Stop Loss
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/paulpas-risk-stop-loss/badge)](https://www.skillsdirectory.com/skills/paulpas-risk-stop-loss)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---




name: risk-stop-loss
compatibility: opencode
completeness: 95
content-types:
- code
- guidance
- config
- do-dont
description: '"Implements stop loss strategies for risk management for risk management
  and algorithmic trading execution."'
license: MIT
maturity: stable
metadata:
  domain: trading
  output-format: code
  related-skills: backtest-drawdown-analysis, exchange-order-execution-api
  role: implementation
  scope: implementation
  triggers: management, risk stop loss, risk-stop-loss, strategies
  archetypes:
  - tactical
  anti_triggers:
  - brainstorming
  - vague ideation
  - no risk management
  response_profile:
    verbosity: low
    directive_strength: high
    abstraction_level: operational
version: "1.0.0"




---




**Role:** Implement stop loss mechanisms to limit losses and protect capital

**Philosophy:** Stop losses are not just price levels; they're risk management tools that should adapt to market conditions

## Key Principles

1. **Stop Types**: Fixed percentage, ATR-based, support/resistance, volatility-adjusted
2. **Trailing Stops**: Lock in profits while limiting losses
3. **Stop Placement**: Avoid stop hunting by placing stops beyond obvious levels
4. **Stop Adjustment**: Modify stops as trade progresses
5. **Emergency Stops**: Automatic closure on extreme events

## Implementation Guidelines

### Structure
- Core logic: risk_engine/stop_loss.py
- Helper functions: risk_engine/stop_strategies.py
- Tests: tests/test_stop_loss.py

### Patterns to Follow
- Support multiple stop types with consistent interface
- Track stop trigger rates for analysis
- Implement dynamic stop adjustment

## Adherence Checklist
Before completing your task, verify:
- [ ] Multiple stop loss types implemented
- [ ] Trailing stop logic handles partial closures
- [ ] Stop levels adapt to volatility
- [ ] Stop placement avoids round numbers
- [ ] Emergency stop triggers on extreme moves


Relative paths in this skill (e.g., scripts/, reference/) are relative to this base directory.

## Python Implementation

### Fixed Percentage Stop
```python
import numpy as np
import pandas as pd
from typing import List, Dict

class StopLossManager:
    def fixed_percentage_stop(self, current_price: float, stop_pct: float = 0.02) -> float:
        """Calculate fixed percentage stop loss based on current price."""
        return current_price * (1 - stop_pct)
```

### Moving Average Stop
```python
    def moving_average_stop(self, current_price: float, moving_average: float, buffer_pct: float = 0.01) -> float:
        """Calculate stop loss using moving average."""
        return moving_average * (1 - buffer_pct)
```

### Price Action Stop
```python
    def price_action_stop(self, current_prices: List[float], period: int) -> float:
        """Calculate stop loss based on the average of the last `period` prices."""
        if len(current_prices) < period:
            raise ValueError("Not enough data points.")
        average_price = sum(current_prices[-period:]) / period
        return average_price * 0.95  # Set stop at 5% below the moving average
```

```python
import numpy as np
import pandas as pd
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from datetime import datetime

@dataclass
class StopLoss:
    """Stop loss configuration."""
    symbol: str
    entry_price: float
    stop_price: float
    stop_type: str
    active: bool
    trail_distance: float = 0
    trail_threshold: float = 0

class StopLossManager:

    def moving_average_stop(self, current_price: float, moving_average: float, buffer_pct: float = 0.01) -> float:
        """Calculate stop loss using moving average."""
        return moving_average * (1 - buffer_pct)

    def fixed_percentage_stop(self, current_price: float, stop_pct: float = 0.02) -> float:
        """Calculate fixed percentage stop loss based on current price."""
        return current_price * (1 - stop_pct)

    def price_action_stop(self, current_prices: List[float], period: int) -> float:
        """Calculate stop loss based on the average of the last `period` prices."""
        if len(current_prices) < period:
            raise ValueError("Not enough data points.")
        average_price = sum(current_prices[-period:]) / period
        return average_price * 0.95  # Set stop at 5% below the moving average

        """Calculate stop loss using moving average."""
        return moving_average * (1 - buffer_pct)

    def fixed_percentage_stop(self, current_price: float, stop_pct: float = 0.02) -> float:
        """Calculate fixed percentage stop loss based on current price."""
        return current_price * (1 - stop_pct)

        """Calculate stop loss using moving average."""
                """Calculate stop loss using moving average."""
        return moving_average * (1 - buffer_pct)

    def price_action_stop(self, current_prices: List[float], period: int) -> float:
        """Calculate stop loss based on the average of the last `period` prices."""
        if len(current_prices) < period:
            raise ValueError("Not enough data points.")
        average_price = sum(current_prices[-period:]) / period
        return average_price * 0.95  # Set stop at 5% below the moving average

    """Manages stop loss strategies across positions."""
    
    def __init__(
        self,
        atr_period: int = 14,
        max_drawdown_pct: float = 0.10
    ):
        self.atr_period = atr_period
        self.max_drawdown_pct = max_drawdown_pct
    
    def fixed_percentage_stop(
        self, entry_price: float, stop_pct: float = 0.02
    ) -> float:
        """Calculate fixed percentage stop loss level."""
        return entry_price * (1 - stop_pct)
    
    def atr_stop(
        self, current_price: float, atr: float, atr_multiplier: float = 2.0
    ) -> float:
        """Calculate ATR-based stop loss."""
        return current_price - (atr * atr_multiplier)
    
    def support_based_stop(
        self, current_price: float, support_level: float, buffer_pct: float = 0.01
    ) -> float:
        """Place stop below support level."""
        return support_level * (1 - buffer_pct)
    
    def trailing_stop(
        self, current_price: float, highest_price: float,
        trail_pct: float = 0.05
    ) -> float:
        """Calculate trailing stop level."""
        trail_distance = highest_price * trail_pct
        return highest_price - trail_distance
    
    def volatility_adjusted_stop(
        self, current_price: float, atr: float,
        recent_volatility: float, base_atr_mult: float = 2.0
    ) -> float:
        """Adjust stop based on current volatility."""
        volatility_ratio = recent_volatility / atr if atr > 0 else 1.0
        adjusted_mult = base_atr_mult * volatility_ratio
        
        return current_price - (atr * adjusted_mult)
    
    def time_decay_stop(
        self, entry_price: float, days_held: int,
        half_life_days: int = 5
    ) -> float:
        """Move stop closer to entry as position ages."""
        decay_factor = np.exp(-days_held / half_life_days)
        return entry_price * (1 - 0.02 * decay_factor)
    
    def dynamic_stop(
        self, price_history: pd.DataFrame, entry_price: float
    ) -> float:
        """Calculate dynamic stop based on price action."""
        if len(price_history) < 20:
            return self.fixed_percentage_stop(entry_price)
        
        # Use ATR for current volatility
        high = price_history['high']
        low = price_history['low']
        close = price_history['close']
        
        tr1 = high - low
        tr2 = abs(high - close.shift())
        tr3 = abs(low - close.shift())
        tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
        atr = tr.tail(14).mean()
        
        # Stop below recent low
        recent_low = price_history['low'].tail(10).min()
        
        return min(
            self.atr_stop(entry_price, atr),
            self.support_based_stop(entry_price, recent_low)
        )
    
    def emergency_stop(
        self, current_price: float, entry_price: float,
        max_loss_pct: float = 0.15
    ) -> float:
        """Immediate stop if price moves against position."""
        max_loss_amount = entry_price * max_loss_pct
        
        if current_price < entry_price - max_loss_amount:
            return current_price * 0.95  # Immediate closure
        elif current_price > entry_price + max_loss_amount:
            return entry_price + max_loss_amount * 0.5  # Lock in profit
        
        return None  # No emergency stop needed
    
    def update_trailing_stops(
        self, positions: List[Dict], current_prices: Dict[str, float]
    ) -> Dict[str, float]:
        """Update trailing stops for all active positions."""
        updated_stops = {}
        
        for position in positions:
            symbol = position['symbol']
            entry_price = position['entry_price']
            highest_price = position.get('highest_price', entry_price)
            trail_pct = position.get('trail_pct', 0.05)
            
            current_price = current_prices.get(symbol, entry_price)
            
            # Update highest price
            new_highest = max(highest_price, current_price)
            
            # Calculate new stop
            new_stop = self.trailing_stop(current_price, new_highest, trail_pct)
            
            updated_stops[symbol] = new_stop
            
            # Update position with new highest price
            position['highest_price'] = new_highest
        
        return updated_stops
```

---

---

## Constraints

### MUST DO
- Calculate position sizing using a risk-per-trade percentage of portfolio equity, not a fixed dollar amount
- Implement layered risk controls: stop loss → drawdown limit → portfolio-level circuit breaker → kill switch
- Compute VaR using historical simulation with at least 1 year of data and multiple confidence levels (95%, 99%)
- Track correlation matrices across all open positions and flag portfolios where top-3 correlations exceed 0.8
- Log all risk events (stop hits, drawdown warnings, kill switches) with full context including P&L, position state, and market conditions

### MUST NOT DO
- Do not use a stop loss as the sole risk control — always layer with portfolio-level limits
- Avoid recalculating position sizes during active drawdown without regime analysis — volatility is likely elevated
- Never allow a single position to exceed 5% of portfolio equity regardless of signal strength or confidence score
- Do not backtest risk metrics without including slippage, commissions, and partial fills in the simulation
- Avoid using standard deviation alone for VaR when returns show fat tails — use historical simulation or EVT


## Live References

> Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.

- [Stop Loss Explained](https://www.investopedia.com/terms/s/stoploss.asp)
- [Trailing Stop Loss Strategies](https://www.investopedia.com/terms/t/trailing-stop.asp)
- [ATR-Based Stop Loss Placement](https://en.wikipedia.org/wiki/Average_true_range)
- [Stop Loss Order Types](https://www.investopedia.com/trading/stop-loss-orders/)
- [Risk Management with Stops](https://docs.quantconnect.com/tutorials/risk-management)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.