← Назад к главному
# risk.rs - Модуль анализа рисков
## 📋 Назначение модуля
`risk_check()` анализирует рыночные риски и возвращает отчёт `RiskReport` для стратегий.
**Основная логика:**
1. **Анализ дельты** (разница между текущей и предыдущей ценой)
2. **Проверка резких движений** (delta > 1% или 15%)
3. **Проверка позиций** (нет позиций → нет рисков)
4. **Возврат отчёта** с уровнем риска (None, HighDelta, HighLeverage, FastMove)
**Используется в:**
- `step.rs` - вызывается на каждом live_step
- Стратегии получают `RiskReport` и могут учитывать риски
---
## 🏗️ Структура модуля
### Enum `RiskLevel`
**Строки:** 10-15
```rust
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RiskLevel {
None, // всё ок
HighDelta, // дельта начинает разбегаться
HighLeverage, // слишком много маржи
FastMove, // резкое движение против позиции
}
```
**Назначение:** Определяет тип рыночной угрозы
**Значения:**
| RiskLevel | Описание |
|-----------|----------|
| `None` | Всё ок, нет рисков |
| `HighDelta` | Дельта начинает разбегаться (delta > 1%) |
| `HighLeverage` | Слишком много маржи (расширение) |
| `FastMove` | Резкое движение против позиции (delta > 15%) |
---
### Структура `RiskReport`
**Строки:** 21-28
```rust
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RiskReport {
pub level: RiskLevel, // Уровень риска
pub delta: f64, // Delta (разница позиций)
pub unrealized: f64, // Нереализованный PnL
pub price_change: f64, // Изменение цены (%)
}
```
**Назначение:** Отчёт о рисках
**Поля:**
| Поле | Тип | Описание |
|------|-----|----------|
| `level` | RiskLevel | Уровень риска |
| `delta` | f64 | Delta (разница между LONG и SHORT) |
| `unrealized` | f64 | Нереализованный PnL |
| `price_change` | f64 | Изменение цены (%) |
---
## 🔄 Основные функции
### Функция `RiskReport::none()`
**Строки:** 31-38
**Сигнатура:**
```rust
pub fn none() -> Self
```
**Возвращает:** Пустой отчёт (нет рисков)
**Алгоритм:**
```rust
pub fn none() -> Self {
Self {
level: RiskLevel::None,
delta: 0.0,
unrealized: 0.0,
price_change: 0.0,
}
}
```
**Пример:**
```rust
let report = RiskReport::none();
report = RiskReport {
level: None,
delta: 0.0,
unrealized: 0.0,
price_change: 0.0,
}
```
---
### Функция `risk_check()`
**Строки:** 49-93
**Сигнатура:**
```rust
pub fn risk_check(pos: &PositionSnapshot, meta_prev: &TradingMeta, meta_now: &TradingMeta) -> RiskReport
```
**Возвращает:**
- `RiskReport` - отчёт о рисках
**Алгоритм (5 этапов):**
---
#### Этап 1: Проверка пустой позиции
**Строки:** 51-53
```rust
if pos.long_qty == 0.0 && pos.short_qty == 0.0 {
return RiskReport::none();
}
```
**Назначение:** Если нет позиций → нет рисков
**Пример:**
```
long_qty = 0, short_qty = 0
return RiskReport::none()
```
---
#### Этап 2: Расчёт дельты и PnL
**Строки:** 55-56
```rust
let delta = pos.delta();
let unreal = pos.unrealized();
```
**Формулы:**
- `delta = long_qty - short_qty`
- `unrealized = unrealized()`
**Пример:**
```
long_qty = 1000, short_qty = 500
delta = 1000 - 500 = 500
unrealized = 0.06 USDT
```
---
#### Этап 3: Расчёт изменения цены
**Строки:** 59-64
```rust
let move_abs = (meta_now.price - meta_prev.price).abs();
let move_pct = if meta_prev.price > 0.0 {
move_abs / meta_prev.price
} else {
0.0
};
```
**Формулы:**
- `move_abs = |price_now - price_prev|`
- `move_pct = move_abs / price_prev` (если `price_prev > 0`)
**Пример 1 (Рост):**
```
meta_prev.price = 0.002000
meta_now.price = 0.002060
move_abs = |0.002060 - 0.002000| = 0.000060
move_pct = 0.000060 / 0.002000 = 3.0%
```
**Пример 2 (Падение):**
```
meta_prev.price = 0.002000
meta_now.price = 0.001940
move_abs = |0.001940 - 0.002000| = 0.000060
move_pct = 0.000060 / 0.002000 = 3.0%
```
**Пример 3 (price_prev = 0):**
```
meta_prev.price = 0.0
meta_now.price = 0.002060
move_abs = |0.002060 - 0.0| = 0.002060
move_pct = 0.0
```
---
#### Этап 4: Проверка HighDelta (дельта > 1%)
**Строки:** 67-74
```rust
if delta.abs() > 1.0 {
return RiskReport {
level: RiskLevel::HighDelta,
delta,
unrealized,
price_change: move_pct,
};
}
```
**Условие:** `|delta| > 1.0`
**Назначение:** Дельта начинает разбегаться
**Пример:**
```
long_qty = 1000, short_qty = 500
delta = 500
|delta| = 500 > 1.0 ✅
return RiskReport {
level: HighDelta,
delta: 500.0,
unrealized: 0.06,
price_change: 3.0,
}
```
---
#### Этап 5: Проверка FastMove (движение > 15%)
**Строки:** 76-83
```rust
if move_pct > 0.15 {
return RiskReport {
level: RiskLevel::FastMove,
delta,
unrealized,
price_change: move_pct,
};
}
```
**Условие:** `move_pct > 0.15` (15%)
**Назначение:** Резкое движение против позиции
**Пример:**
```
meta_prev.price = 0.002000
meta_now.price = 0020.3000 (300% рост!)
move_pct = 300.0 > 0.15 ✅
return RiskReport {
level: FastMove,
delta: 1000.0,
unrealized: 0.06,
price_change: 300.0,
}
```
---
#### Этап 6: Мягкий риск (всё ок)
**Строки:** 86-92
```rust
RiskReport {
level: RiskLevel::None,
delta,
unrealized,
price_change: move_pct,
}
```
**Условие:** Все проверки пройдены
**Пример:**
```
delta = 0 (LONG = SHORT)
move_pct = 1.0% (допустимо)
return RiskReport {
level: None,
delta: 0.0,
unrealized: 0.06,
price_change: 1.0,
}
```
---
## 📊 Уровни риска
### None (Нет риска)
**Условия:**
- Нет позиций
**Действия:**
- Нет действий
**Пример:**
```
long_qty = 0, short_qty = 0
RiskReport {
level: None,
delta: 0.0,
unrealized: 0.0,
price_change: 0.0,
}
```
---
### HighDelta (Дельта разбегается)
**Условие:**
- `|delta| > 1.0`
**Действия:**
- Стратегии могут быть более осторожными
- Увеличить коолдау между резками
**Пример:**
```
long_qty = 1000, short_qty = 0
delta = 1000 > 1.0 ✅
RiskReport {
level: HighDelta,
delta: 1000.0,
unrealized: 0.06,
price_change: 1.0,
}
```
---
### FastMove (Резкое движение)
**Условие:**
- `move_pct > 0.15` (15%)
**Действия:**
- Экстренный хедж (через HedgeGuard)
- Прекратить резки
**Пример:**
```
meta_prev.price = 0.002000
meta_now.price = 0020.3000 (300% рост!)
RiskReport {
level: FastMove,
delta: 1000.0,
unrealized: 0.06,
price_change: 300.0,
}
```
---
### HighLeverage (Много маржи)
**Условие:**
- (зарезервирован для будущего)
**Действия:**
- Не увеличивать маржу
- Закрыть часть позиции
**Пример:**
```
RiskReport {
level: HighLeverage,
delta: 500.0,
unrealized: 0.06,
price_change: 3.0,
}
```
---
## ⚠️ Критические моменты
### 1. Никаких direct-операций
**Строки:** 45-47
```rust
/// ⚠️ ВАЖНО:
/// Никаких direct-операций тут нет.
/// Только сигнализация.
```
**Что это значит:**
- `risk_check()` НЕ закрывает позиции
- `risk_check()` НЕ открывает хедж
- `risk_check()` ТОЛЬКО сигнализирует
**Кто принимает решения:**
- `step.rs` - вызывает `risk_check()` и игнорирует результат
- `strategy_single.rs` - может игнорировать `RiskReport`
- `strategy_both.rs` - может игнорировать `RiskReport`
- `hedge_guard.rs` - сам принимает решение о хедже
---
### 2. Delta ≠ изменение цены
**Различие между:**
- `delta` = long_qty - short_qty (разница позиций)
- `price_change = move_pct` (изменение цены в %)
**Пример:**
```
LONG = 1000, SHORT = 500
delta = 1000 - 500 = 500 (разница позиций)
meta_prev.price = 0.002000
meta_now.price = 0.002060
price_change = (0.002060 - 0.002000) / 0.002000 × 100 = 3.0%
```
---
### 3. move_pct при price_prev = 0
**Строки:** 61-64
```rust
let move_pct = if meta_prev.price > 0.0 {
move_abs / meta_prev.price
} else {
0.0
};
```
**Логика:**
- Если `price_prev == 0` → `move_pct = 0`
- Иначе → `move_pct = move_abs / price_prev`
**Пример:**
```
meta_prev.price = 0.0
meta_now.price = 0.002060
move_abs = 0.002060
move_pct = 0.0 (избегаем деления на ноль)
```
---
## 📚 Связанные файлы
| Файл | Связь |
|------|-------|
| `src/live/state.rs` | PositionSnapshot |
| `src/live/meta.rs` | TradingMeta |
| `src/live/step.rs` | Вызывает risk_check() |
---
## 🎯 Резюме
**Что делает risk.rs:**
1. ✅ Анализирует рыночные риски
2. ✅ Возвращает отчёт `RiskReport` с уровнем риска
3. ✅ Определяет тип угрозы (None, HighDelta, HighLeverage, FastMove)
4. ✅ Только сигнализация (никаких direct-операций)
**Уровни риска:**
- `None` - всё ок, нет рисков
- `HighDelta` - дельта разбегается (|delta| > 1.0)
- `HighLeverage` - слишком много маржи (зарезервировано)
- `FastMove` - резкое движение (price_change > 15%)
**RiskReport поля:**
- `level` - уровень риска
- `delta` - разница позиций
- `unrealized` - нереализованный PnL
- `price_change` - изменение цены (%)
**Критический момент:**
- 🔥 `risk_check()` ТОЛЬКО сигнализирует
- 🔥 Никаких direct-операций
- 🔥 Стратегии сами принимают решения
---
**Дата создания:** 2026-02-22
**Автор:** Claude Code Assistant
**Версия:** 1.0