# `DeltaCalc.Safety`
[🔗](https://github.com/ZenHive/delta_calc/blob/v0.3.0/lib/delta_calc/safety.ex#L1)

Position safety scoring and before/after DCA safety comparisons.

## API Functions
| Function | Arity | Description | Param Kinds |
| --- | --- | --- | --- |
| `compare_dca_safety` | 8 | Compare safety metrics before and after adding a DCA leg. | `single_leg: value`, `dca_leg: value`, `current_price: value`, `initial_equity: value`, `mmr: value`, `side: value`, `swan_pct: value`, `safety_cfg: value` |
| `safety` | 5 | Evaluate position safety and compute risk metrics. | `liq: value`, `entry: value`, `swan_pct: value`, `side: value`, `cfg: value` |

# `safety_result`

```elixir
@type safety_result() :: map() | {:error, :non_positive_entry}
```

# `compare_dca_safety`

```elixir
@spec compare_dca_safety(
  map(),
  map(),
  Decimal.t(),
  Decimal.t(),
  Decimal.t(),
  :long | :short,
  Decimal.t(),
  map()
) :: map() | {:error, atom()}
```

Compare safety metrics before and after adding a DCA leg.

## Parameters

  * `single_leg` - Initial leg with :entry and :notional as canonical decimal strings; native Elixir callers may also pass Decimal or integer. (value)
  * `dca_leg` - DCA leg with :entry and :notional as canonical decimal strings; native Elixir callers may also pass Decimal or integer. (value)
  * `current_price` - Market price when adding DCA leg as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `initial_equity` - Starting subaccount equity as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `mmr` - Minimum margin requirement as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `side` - Position side (:long or :short) (value)
  * `swan_pct` - Black swan threshold percentage as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `safety_cfg` - Optional safety configuration whose multiplier fields use canonical decimal strings; native Elixir callers may also pass Decimal or integer. (default: `%{}`, value)

## Returns

Map with pre_dca, post_dca, leverage_change, liquidation_change (`map`)

```elixir
# descripex:contract
%{
  params: %{
    side: %{
      description: "Position side (:long or :short)",
      kind: :value,
      schema: %{"enum" => ["long", "short"], "type" => "string"}
    },
    current_price: %{
      description: "Market price when adding DCA leg as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    initial_equity: %{
      description: "Starting subaccount equity as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    swan_pct: %{
      description: "Black swan threshold percentage as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    single_leg: %{
      description: "Initial leg with :entry and :notional as canonical decimal strings; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{
        "additionalProperties" => false,
        "properties" => %{
          "entry" => %{"type" => "string"},
          "notional" => %{"type" => "string"}
        },
        "required" => ["entry", "notional"],
        "type" => "object"
      }
    },
    dca_leg: %{
      description: "DCA leg with :entry and :notional as canonical decimal strings; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{
        "additionalProperties" => false,
        "properties" => %{
          "entry" => %{"type" => "string"},
          "notional" => %{"type" => "string"}
        },
        "required" => ["entry", "notional"],
        "type" => "object"
      }
    },
    mmr: %{
      description: "Minimum margin requirement as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    safety_cfg: %{
      default: %{},
      description: "Optional safety configuration whose multiplier fields use canonical decimal strings; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{
        "additionalProperties" => false,
        "properties" => %{
          "safe_multiplier" => %{"type" => "string"},
          "threshold_multiplier" => %{"type" => "string"}
        },
        "type" => "object"
      }
    }
  },
  returns: %{
    type: :map,
    description: "Map with pre_dca, post_dca, leverage_change, liquidation_change"
  }
}
```

# `safety`

```elixir
@spec safety(Decimal.t(), Decimal.t(), Decimal.t(), :long | :short, map()) ::
  safety_result()
```

Evaluate position safety and compute risk metrics.

## Parameters

  * `liq` - Liquidation price as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `entry` - Entry price (> 0) as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `swan_pct` - Black swan threshold percentage as a canonical decimal string; native Elixir callers may also pass Decimal or integer. (value)
  * `side` - Position side (:long or :short) (value)
  * `cfg` - Safety config with :threshold_multiplier and :safe_multiplier as canonical decimal strings; native Elixir callers may also pass Decimal or integer. (default: `%{}`, value)

## Returns

Map with verdict, distance metrics, and composite_score, or \{:error, :non_positive_entry\} (`map`)

```elixir
# descripex:contract
%{
  params: %{
    entry: %{
      description: "Entry price (> 0) as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    side: %{
      description: "Position side (:long or :short)",
      kind: :value,
      schema: %{"enum" => ["long", "short"], "type" => "string"}
    },
    liq: %{
      description: "Liquidation price as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    swan_pct: %{
      description: "Black swan threshold percentage as a canonical decimal string; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{"type" => "string"}
    },
    cfg: %{
      default: %{},
      description: "Safety config with :threshold_multiplier and :safe_multiplier as canonical decimal strings; native Elixir callers may also pass Decimal or integer.",
      kind: :value,
      schema: %{
        "additionalProperties" => false,
        "properties" => %{
          "safe_multiplier" => %{"type" => "string"},
          "threshold_multiplier" => %{"type" => "string"}
        },
        "type" => "object"
      }
    }
  },
  returns: %{
    type: :map,
    description: "Map with verdict, distance metrics, and composite_score, or {:error, :non_positive_entry}"
  }
}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
