← Назад к главному
# hedge_guard.rs - Модуль экстренной защиты от сильных движений цены
## 📋 Назначение модуля
`HedgeGuard` обеспечивает экстренную защиту от сильных движений цены против позиции.
**Основная логика:**
1. **Авто-хедж** при отклонении цены ПРОТИВ текущей позиции
2. **Работает когда:** Только LONG или только SHORT (НЕ BOTH)
3. **Порог хеджа:** `delta <= -1.5%` (цена ушла против позиции)
4. **Экстренная защита:** При пустом стакане порог снижается до `-1.75%`
5. **Cooldown:** Не хеджировать N секунд после входа (защита от проскальзывания)
6. **Rate limiting:** Логирование не чаще 1 раза в секунду при cooldown
**Изменения:**
- Раньше: хедж срабатывал только в диапазоне 2–20%
- Теперь: хедж при `|delta| >= 1.5%` (без верхнего лимита)
---
## 🏗️ Структура модуля
### Структура `HedgeSignal`
**Строки:** 21-28
```rust
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct HedgeSignal {
pub long_qty: f64, // LONG qty (текущий или новый)
pub short_qty: f64, // SHORT qty (текущий или новый)
pub add_long: f64, // Сколько добавить LONG
pub add_short: f64, // Сколько добавить SHORT
pub reason: String, // Причина хеджа
}
```
**Назначение:** Сигнал о необходимости хеджа
**Пример:**
```rust
HedgeSignal {
long_qty: 1000.0,
short_qty: 1000.0,
add_long: 0.0,
add_short: 1000.0,
reason: "Auto-hedge LONG: delta -1.5%, add SHORT 1000".to_string(),
}
```
---
### Структура `HedgeGuard`
**Строка:** 30
```rust
pub struct HedgeGuard;
```
**Особенности:** Unit struct (без полей) - вся логика в функциях
---
## 🔄 Основные функции
### Функция `check()`
**Строки:** 46-209
**Сигнатура:**
```rust
pub fn check(
pos: &mut PositionSnapshot, // Состояние позиции (изменяемое)
meta: &TradingMeta, // Метаданные контракта
entry_price: f64, // Entry цена позиции
) -> Option
```
**Возвращает:**
- `Some(HedgeSignal)` - хедж нужен
- `None` - ещё не время или условия не выполнены
**Алгоритм (8 блоков):**
---
#### Блок 1: Проверка цены
```rust
if entry_price <= 0.0 {
return None;
}
let px = meta.price;
if px <= 0.0 {
return None;
}
```
---
#### Блок 2: 🔥🔥 Cooldown защита
**Строки:** 60-72
```rust
// 🔥🔥 COOLDOWN: Не хеджировать N секунд после входа!
let now = chrono::Utc::now().timestamp();
let elapsed = now - pos.last_entry_time;
if elapsed < pos.hedge_cooldown_sec {
// Логируем только 1 раз при начале cooldown
if now - pos.last_cooldown_log_time >= 1 { // Максимум 1 раз в секунду
println!(" ⏸️ ХЕДЖ НА ПАУЗЕ: прошло {} сек из {} сек cooldown",
elapsed, pos.hedge_cooldown_sec);
pos.last_cooldown_log_time = now;
}
return None;
}
```
**Назначение:** Защита от немедленного хеджа сразу после входа
**Параметр:** `pos.hedge_cooldown_sec` (обычно 5 секунд)
**Rate limiting:** Логирование максимум 1 раз в секунду
**Пример:**
```
00:00 → Вход в LONG 1000 по 0.002000
pos.last_entry_time = 1645560000
pos.hedge_cooldown_sec = 5
00:00:01 → price = 0.001970 (-1.5%)
elapsed = 1 сек < 5 сек
⏸️ ХЕДЖ НА ПАУЗЕ: прошло 1 сек из 5 сек cooldown
return None
00:00:02 → price = 0.001950 (-2.5%)
elapsed = 2 сек < 5 сек
⏸️ ХЕДЖ НА ПАУЗЕ: прошло 2 сек из 5 сек cooldown
return None
00:00:05 → elapsed = 5 сек >= 5 сек ✅
Можно хеджироваться
```
---
#### Блок 3: 🚨🚨 Экстренная защита - пустой стакан + резкая свеча
**Строки:** 74-131
```rust
// 🚨🚨 ЧРЕЗВЫЧАЙНАЯ ЗАЩИТА: Пустой стакан + резкая свеча
// Работает ДО обычных проверок, чтобы сработать раньше при опасности
let total_depth = meta.bid_qty_depth + meta.ask_qty_depth;
let depth_threshold = 1000.0; // Порог пустого стакана
if total_depth < depth_threshold {
// Определяем delta в зависимости от типа позиции
let (delta_pct, is_profitable) = if pos.long_qty > 0.0 && pos.entry_long > 0.0 {
// Для LONG: цена вниз = убыток
((px - pos.entry_long) / pos.entry_long * 100.0, px >= pos.entry_long)
} else if pos.short_qty > 0.0 && pos.entry_short > 0.0 {
// Для SHORT: цена вниз = прибыль, цена вверх = убыток
((pos.entry_short - px) / pos.entry_short * 100.0, px <= pos.entry_short)
} else {
(0.0, false)
};
// При пустом стакане снижаем порог до ±1.75%
// Хеджируем когда движение ПРОТИВ позиции (delta имеет "неправильный" знак)
let need_hedge = if pos.long_qty > 0.0 {
// LONG: хедж когда delta <= -1.75% (цена вниз)
delta_pct <= -1.75
} else if pos.short_qty > 0.0 {
// SHORT: хедж когда delta <= -1.75% (цена вверх, значит delta отрицательный)
delta_pct <= -1.75
} else {
false
};
if need_hedge {
println!(" 🚨🚨 ЧРЕЗВЫЧАЙНЫЙ ХЕДЖ!");
println!(" - Пустой стакан: depth={:.2} < {:.2}", total_depth, depth_threshold);
println!(" - Резкое движение: {:.2}% (экстренный порог ±1.75%)", delta_pct);
// Определяем какую сторону хеджировать
if pos.long_qty > 0.0 && pos.short_qty == 0.0 {
// LONG в опасности - добавляем SHORT
let hedge_qty = pos.long_qty;
return Some(HedgeSignal {
long_qty: pos.long_qty,
short_qty: hedge_qty,
add_long: 0.0,
add_short: hedge_qty,
reason: format!("🚨 EMERGENCY: Пустой стакан + резкая свеча {:.2}%", delta_pct),
});
} else if pos.short_qty > 0.0 && pos.long_qty == 0.0 {
// SHORT в опасности - добавляем LONG
let hedge_qty = pos.short_qty;
return Some(HedgeSignal {
long_qty: hedge_qty,
short_qty: pos.short_qty,
add_long: hedge_qty,
add_short: 0.0,
reason: format!("🚨 EMERGENCY: Пустой стакан + резкая свеча {:.2}%", delta_pct),
});
}
}
}
```
**Назначение:** Экстренная защита при пустом стакане + резком движении
**Условия:**
1. `total_depth < 1000` (пустой стакан)
2. `delta_pct <= -1.75%` (движение против позиции)
**Порог:**
- Обычный хедж: `-1.5%`
- Экстренный (пустой стакан): `-1.75%`
**Почему экстренный порог ниже (-1.75% < -1.5%):**
- Пустой стакан = высокая волатильность
- Хеджируем раньше (при меньшем движении)
- Защита от ликвидации
**Пример LONG:**
```
LONG: qty=1000, entry=0.002000
Стакан: bid_qty_depth=500, ask_qty_depth=200
total_depth = 500 + 200 = 700 < 1000 ✅
price = 0.001965 (-1.75%)
delta_pct = (0.001965 - 0.002000) / 0.002000 × 100 = -1.75%
need_hedge = delta_pct <= -1.75?
= -1.75 <= -1.75? ✅
🚨🚨 ЧРЕЗВЫЧАЙНЫЙ ХЕДЖ!
- Пустой стакан: depth=700.00 < 1000.00
- Резкое движение: -1.75% (экстренный порог ±1.75%)
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 0.0,
add_short: 1000,
reason: "🚨 EMERGENCY: Пустой стакан + резкая свеча -1.75%"
}
```
**Пример SHORT:**
```
SHORT: qty=1000, entry=0.002000
Стакан: bid_qty_depth=500, ask_qty_depth=200
total_depth = 700 < 1000 ✅
price = 0.002035 (+1.75%)
delta_pct = (0.002000 - 0.002035) / 0.002000 × 100 = -1.75%
need_hedge = delta_pct <= -1.75?
= -1.75 <= -1.75? ✅
🚨🚨 ЧРЕЗВЫЧАЙНЫЙ ХЕДЖ!
- Пустой стакан: depth=700.00 < 1000.00
- Резкое движение: -1.75% (экстренный порог ±1.75%)
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 1000,
add_short: 0.0,
reason: "🚨 EMERGENCY: Пустой стакан + резкая свеча -1.75%"
}
```
---
#### Блок 4: Защита от дочедживания
**Строки:** 133-139
```rust
// ЗАЩИТА: Не хеджировать если уже хедж есть
if pos.long_qty > 0.0 && pos.short_qty > 0.0 {
// Проверяем нужно ли дочедживание
if pos.long_qty <= pos.short_qty {
return None; // Хедж уже достаточный или избыточный
}
}
```
**Назначение:** Защита от дочедживания если хедж уже достаточный
**Логика:**
- Если `long_qty > 0` **и** `short_qty > 0` → BOTH уже есть
- Если `long_qty <= short_qty` → хедж достаточный или избыточный
- Если `long_qty > short_qty` → можно дочедживать (LONG больше)
**Пример:**
```
Сценарий 1: Хедж уже есть (равный)
LONG: qty=1000, SHORT: qty=1000
long_qty <= short_qty? 1000 <= 1000? ✅
return None (хедж достаточный)
Сценарий 2: Хедж избыточный
LONG: qty=1000, SHORT: qty=1200
long_qty <= short_qty? 1000 <= 1200? ✅
return None (хедж избыточный)
Сценарий 3: Можно дочедживать
LONG: qty=1200, SHORT: qty=1000
long_qty <= short_qty? 1200 <= 1000? ❌
Можно дочедживать (добавить 200 SHORT)
```
---
#### Блок 5: Проверка LONG позиции (одиночная)
**Строки:** 141-170
```rust
// -------------------
// Проверка LONG позиции (одиночная)
// -------------------
if pos.long_qty > 0.0 && pos.short_qty == 0.0 {
let delta_pct = (px - pos.entry_long) / pos.entry_long * 100.0;
// ОТЛАДКА - логируем только каждые 5 секунд ИЛИ при критическом значении
let should_log = delta_pct <= -2.0 || (now - pos.last_cooldown_log_time >= 5);
if should_log {
println!(" 📊 LONG хедж проверка: entry={}, current={}, delta_pct={:.3}%",
pos.entry_long, px, delta_pct);
pos.last_cooldown_log_time = now;
}
// Цена ушла против LONG вниз на 1.5% и более (экстренная защита)
if delta_pct <= -1.5 {
println!(" 🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct={:.3}% <= -1.5%", delta_pct);
// Для одиночной LONG позиции хедж = SHORT того же размера
let hedge_qty = pos.long_qty;
return Some(HedgeSignal {
long_qty: pos.long_qty, // LONG остается тем же
short_qty: hedge_qty, // Новый SHORT размера LONG
add_long: 0.0, // НЕ добавляем LONG
add_short: hedge_qty, // Добавляем SHORT
reason: format!("Auto-hedge LONG: delta {:.2}%, add SHORT {}", delta_pct, hedge_qty),
});
}
}
```
**Условия:**
1. `pos.long_qty > 0` (LONG есть)
2. `pos.short_qty == 0` (SHORT нет) - одиночная позиция
**Расчёт delta:**
```
delta_pct = (current_price - entry_long) / entry_long × 100
```
**Логирование:**
- Каждые 5 секунд
- ИЛИ при `delta_pct <= -2.0%` (критическое значение)
**Порог хеджа:**
- `delta_pct <= -1.5%` (цена ушла вниз против LONG)
**Действия:**
- `hedge_qty = long_qty`
- `OpenShort(hedge_qty, price)`
**Пример:**
```
LONG: qty=1000, entry=0.002000
price = 0.001970
delta_pct = (0.001970 - 0.002000) / 0.002000 × 100 = -1.5%
Проверка:
-1.5 <= -1.5? ✅
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5%
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 0.0,
add_short: 1000,
reason: "Auto-hedge LONG: delta -1.5%, add SHORT 1000"
}
```
---
#### Блок 6: Проверка SHORT позиции (одиночная)
**Строки:** 172-206
```rust
// -------------------
// Проверка SHORT позиции (одиночная)
// -------------------
if pos.short_qty > 0.0 && pos.long_qty == 0.0 {
// Для SHORT: цена ВНИЗ = прибыль, цена ВВЕРХ = убыток
let delta_pct = (pos.entry_short - px) / pos.entry_short * 100.0;
// ОТЛАДКА - логируем только каждые 5 секунд ИЛИ при критическом значении
let should_log = delta_pct >= 2.0 || (now - pos.last_cooldown_log_time >= 5);
if should_log {
println!(" 📊 SHORT хедж проверка: entry={}, current={}, delta_pct={:.3}% ({}: {})",
pos.entry_short, px, delta_pct,
if delta_pct > 0.0 { "ПРИБЫЛЬ" } else { "УБЫТОК" },
if delta_pct > 0.0 { "цена вниз" } else { "цена вверх" }
);
pos.last_cooldown_log_time = now;
}
// Цена ушла против SHORT ВВЕРХ на 1.5% и более (экстренная защита)
// delta_pct будет ОТРИЦАТЕЛЬНЫМ когда цена растет против SHORT
if delta_pct <= -1.5 {
println!(" 🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct={:.3}% <= -1.5% (цена вверх против SHORT)", delta_pct);
// Для одиночной SHORT позиции хедж = LONG того же размера
let hedge_qty = pos.short_qty;
return Some(HedgeSignal {
long_qty: hedge_qty, // Новый LONG размера SHORT
short_qty: pos.short_qty, // SHORT остается тем же
add_long: hedge_qty, // Добавляем LONG
add_short: 0.0, // НЕ добавляем SHORT
reason: format!("Auto-hedge SHORT: delta {:.2}%, add LONG {}", delta_pct, hedge_qty),
});
}
}
```
**Условия:**
1. `pos.short_qty > 0` (SHORT есть)
2. `pos.long_qty == 0` (LONG нет) - одиночная позиция
**Расчёт delta:**
```
delta_pct = (entry_short - current_price) / entry_short × 100
```
**Интерпретация delta для SHORT:**
- `delta_pct > 0` → цена вниз → прибыль
- `delta_pct < 0` → цена вверх → убыток
**Логирование:**
- Каждые 5 секунд
- ИЛИ при `delta_pct >= 2.0%` (критическое значение в прибыль)
**Порог хеджа:**
- `delta_pct <= -1.5%` (цена ушла вверх против SHORT)
**Действия:**
- `hedge_qty = short_qty`
- `OpenLong(hedge_qty, price)`
**Пример:**
```
SHORT: qty=1000, entry=0.002000
price = 0.002030
delta_pct = (0.002000 - 0.002030) / 0.002000 × 100 = -1.5%
Интерпретация:
delta_pct = -1.5% < 0 → цена вверх → убыток ❌
Проверка:
-1.5 <= -1.5? ✅
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5% (цена вверх против SHORT)
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 1000,
add_short: 0.0,
reason: "Auto-hedge SHORT: delta -1.5%, add LONG 1000"
}
```
---
#### Блок 7: Возврат None
**Строка:** 208
```rust
None
```
**Если ни одно условие не выполнилось:**
- Порог не достигнут
- BOTH режим (хедж уже есть)
- Cooldown ещё прошёл
---
### Функция `execute()`
**Строки:** 217-242
**Сигнатура:**
```rust
pub fn execute(
pos: &PositionSnapshot, // Состояние позиции
sig: HedgeSignal, // Сигнал хеджа
px: f64, // Текущая цена
) -> Vec
```
**Возвращает:** `Vec` - список действий для исполнения
**Логика:**
```rust
println!("🛡️ ХЕДЖ СИГНАЛ: {}", sig.reason);
// Был незахеджированный LONG — добавляем SHORT
if pos.long_qty > 0.0 && pos.short_qty == 0.0 {
if sig.short_qty > 0.0 {
actions.push(LiveAction::OpenShort(sig.short_qty, px));
}
}
// Был незахеджированный SHORT — добавляем LONG
if pos.short_qty > 0.0 && pos.long_qty == 0.0 {
if sig.long_qty > 0.0 {
actions.push(LiveAction::OpenLong(sig.long_qty, px));
}
}
println!("📊 ХЕДЖ создал {} actions", actions.len());
```
**Пример LONG:**
```
До хеджа:
- LONG: qty=1000
- SHORT: qty=0
HedgeSignal:
- long_qty=1000, short_qty=1000
- add_long=0.0, add_short=1000
execute():
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge LONG: delta -1.5%, add SHORT 1000
if long_qty > 0 && short_qty == 0:
OpenShort(1000, 0.001970)
📊 ХЕДЖ создал 1 actions
После хеджа:
- LONG: qty=1000
- SHORT: qty=1000
```
**Пример SHORT:**
```
До хеджа:
- LONG: qty=0
- SHORT: qty=1000
HedgeSignal:
- long_qty=1000, short_qty=1000
- add_long=1000, add_short=0.0
execute():
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge SHORT: delta -1.5%, add LONG 1000
if short_qty > 0 && long_qty == 0:
OpenLong(1000, 0.002030)
📊 ХЕДЖ создал 1 actions
После хеджа:
- LONG: qty=1000
- SHORT: qty=1000
```
---
## 📊 Полный граф работы
```
check()
↓
├─→ Проверка цены (entry_price, price)
├─→ Проверка Cooldown (N сек после входа)
│ ├─→ elapsed < N сек → return None
│ └─→ elapsed >= N сек → продолжаем
│
├─→ Экстренная защита (пустой стакан)
│ ├─→ total_depth < 1000?
│ ├─→ delta_pct <= -1.75%?
│ └─→ Some(HedgeSignal) ✅
│
├─→ Проверка дочедживания (BOTH уже есть)
│ └─→ long_qty <= short_qty → return None
│
├─→ Проверка LONG (одиночная)
│ ├─→ delta_pct = (price - entry_long) / entry_long × 100
│ ├─→ delta_pct <= -1.5%?
│ │ ├─→ Да → Some(HedgeSignal) ✅
│ │ └─→ Нет → продолжаем
│
└─→ Проверка SHORT (одиночная)
├─→ delta_pct = (entry_short - price) / entry_short × 100
├─→ delta_pct <= -1.5%?
│ ├─→ Да → Some(HedgeSignal) ✅
│ └─→ Нет → return None
execute(sig)
↓
├─→ 🛡️ ХЕДЖ СИГНАЛ: reason
│
├─→ if long_qty > 0 && short_qty == 0:
│ └─→ OpenShort(add_short, price)
│
├─→ if short_qty > 0 && long_qty == 0:
│ └─→ OpenLong(add_long, price)
│
└─→ 📊 ХЕДЖ создал X actions
```
---
## 🎯 Сценарии работы
### Сценарий 1: Обычный хедж LONG
```
00:00 → Вход в LONG 1000 по 0.002000
pos.last_entry_time = 1645560000
pos.hedge_cooldown_sec = 5
00:05 → elapsed = 5 сек >= 5 сек ✅
price = 0.001970
check():
delta_pct = (0.001970 - 0.002000) / 0.002000 × 100 = -1.5%
Проверка:
-1.5 <= -1.5? ✅
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5%
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 0.0,
add_short: 1000,
reason: "Auto-hedge LONG: delta -1.5%, add SHORT 1000"
}
execute():
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge LONG: delta -1.5%, add SHORT 1000
OpenShort(1000, 0.001970)
📊 ХЕДЖ создал 1 actions
После хеджа:
- LONG: qty=1000
- SHORT: qty=1000
→ BothStrategy берёт управление
```
---
### Сценарий 2: Обычный хедж SHORT
```
00:00 → Вход в SHORT 1000 по 0.002000
pos.last_entry_time = 1645560000
pos.hedge_cooldown_sec = 5
00:05 → elapsed = 5 сек >= 5 сек ✅
price = 0.002030
check():
delta_pct = (0.002000 - 0.002030) / 0.002000 × 100 = -1.5%
Интерпретация:
delta_pct = -1.5% < 0 → цена вверх → убыток ❌
Проверка:
-1.5 <= -1.5? ✅
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5% (цена вверх против SHORT)
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 1000,
add_short: 0.0,
reason: "Auto-hedge SHORT: delta -1.5%, add LONG 1000"
}
execute():
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge SHORT: delta -1.5%, add LONG 1000
OpenLong(1000, 0.002030)
📊 ХЕДЖ создал 1 actions
После хеджа:
- LONG: qty=1000
- SHORT: qty=1000
→ BothStrategy берёт управление
```
---
### Сценарий 3: Экстренный хедж (пустой стакан + резкая свеча)
```
00:00 → Вход в LONG 1000 по 0.002000
00:05 → elapsed = 5 сек >= 5 сек ✅
Стакан: bid_qty_depth=200, ask_qty_depth=300
total_depth = 500 < 1000 ✅
price = 0.001965 (-1.75%)
check():
Экстренная защита:
total_depth = 500 < 1000 ✅
delta_pct = (0.001965 - 0.002000) / 0.002000 × 100 = -1.75%
Проверка:
-1.75 <= -1.75? ✅
🚨🚨 ЧРЕЗВЫЧАЙНЫЙ ХЕДЖ!
- Пустой стакан: depth=500.00 < 1000.00
- Резкое движение: -1.75% (экстренный порог ±1.75%)
HedgeSignal {
long_qty: 1000,
short_qty: 1000,
add_long: 0.0,
add_short: 1000,
reason: "🚨 EMERGENCY: Пустой стакан + резкая свеча -1.75%"
}
execute():
OpenShort(1000, 0.001965)
После хеджа:
- LONG: qty=1000
- SHORT: qty=1000
```
---
### Сценарий 4: Cooldown защита
```
00:00 → Вход в LONG 1000 по 0.002000
pos.last_entry_time = 1645560000
pos.hedge_cooldown_sec = 5
00:00:01 → price = 0.001970 (-1.5%)
elapsed = 1 сек < 5 сек ❌
check():
⏸️ ХЕДЖ НА ПАУЗЕ: прошло 1 сек из 5 сек cooldown
return None
00:00:02 → price = 0.001950 (-2.5%)
elapsed = 2 сек < 5 сек ❌
check():
⏸️ ХЕДЖ НА ПАУЗЕ: прошло 2 сек из 5 сек cooldown
return None
00:00:05 → elapsed = 5 сек >= 5 сек ✅
price = 0.001945 (-2.75%)
check():
elapsed = 5 сек >= 5 сек ✅
delta_pct = (0.001945 - 0.002000) / 0.002000 × 100 = -2.75%
Проверка:
-2.75 <= -1.5? ✅
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-2.750% <= -1.5%
HedgeSignal {...}
execute():
OpenShort(1000, 0.001945)
```
---
### Сценарий 5: НЕ хеджируем (BOTH уже есть)
```
00:00 → Вход в LONG 1000
01:00 → Хедж сработал
Открыт SHORT 1000
01:05 → price = 0.001940 (-3.0%)
check():
Проверка дочедживания:
long_qty = 1000 > 0 ✅
short_qty = 1000 > 0 ✅
long_qty <= short_qty? 1000 <= 1000? ✅
return None (хедж уже достаточный)
Ещё проверка:
Допустим LONG = 1200, SHORT = 1000
check():
long_qty <= short_qty? 1200 <= 1000? ❌
Можно дочедживать (добавить 200 SHORT)
```
---
### Сценарий 6: Логирование каждые 5 секунд
```
00:00 → Вход в LONG 1000
00:05 → elapsed = 5 сек >= 5 сек ✅
price = 0.002010 (+0.5%)
check():
delta_pct = (0.002010 - 0.002000) / 0.002000 × 100 = +0.5%
should_log = delta_pct <= -2.0 || (now - last_log >= 5)
= false || true = true ✅
📊 LONG хедж проверка: entry=0.002000, current=0.002010, delta_pct=+0.500%
Проверка:
0.5 <= -1.5? ❌
return None
00:10 → price = 0.002020 (+1.0%)
check():
delta_pct = +1.0%
should_log = false || true = true ✅
📊 LONG хедж проверка: entry=0.002000, current=0.002020, delta_pct=+1.000%
Проверка:
1.0 <= -1.5? ❌
return None
00:15 → price = 0.001980 (-1.0%)
check():
delta_pct = -1.0%
should_log = false || true = true ✅
📊 LONG хедж проверка: entry=0.002000, current=0.001980, delta_pct=-1.000%
Проверка:
-1.0 <= -1.5? ❌
return None
00:20 → price = 0.001970 (-1.5%)
check():
delta_pct = -1.5%
should_log = true || true = true ✅
📊 LONG хедж проверка: entry=0.002000, current=0.001970, delta_pct=-1.500%
Проверка:
-1.5 <= -1.5? ✅
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5%
```
---
## ⚠️ Критические моменты
### 1. Cooldown защита
**Назначение:** Защита от немедленного хеджа после входа
**Параметр:** `pos.hedge_cooldown_sec` (обычно 5 секунд)
**Rate limiting:** Логирование максимум 1 раз в секунду
**Почему важно:**
- Сразу после входа может быть проскальзывание
- Нельзя хеджироваться на ложном движении
---
### 2. Экстренная защита (пустой стакан)
**Условия:**
1. `total_depth < 1000` (пустой стакан)
2. `delta_pct <= -1.75%` (движение против позиции)
**Порог:**
- Обычный хедж: `-1.5%`
- Экстренный: `-1.75%`
**Почему экстренный порог ниже:**
- Пустой стакан = высокая волатильность
- Хеджируем раньше (при меньшем движении)
- Защита от ликвидации
---
### 3. Формула delta для LONG vs SHORT
**Для LONG:**
```rust
delta_pct = (price - entry_long) / entry_long × 100
```
- `delta_pct > 0` → цена выше → прибыль
- `delta_pct < 0` → цена ниже → убыток
**Для SHORT:**
```rust
delta_pct = (entry_short - price) / entry_short × 100
```
- `delta_pct > 0` → цена ниже → прибыль
- `delta_pct < 0` → цена выше → убыток
**Ошибка:** Если перепутать формулы → неправильные триггеры!
---
### 4. Защита от дочедживания
**Условие:**
```rust
if pos.long_qty > 0.0 && pos.short_qty > 0.0 {
if pos.long_qty <= pos.short_qty {
return None; // Хедж уже достаточный или избыточный
}
}
```
**Логика:**
- Если BOTH уже есть → НЕ хеджируем
- Если `long_qty <= short_qty` → хедж достаточный или избыточный
- Если `long_qty > short_qty` → можно дочедживать
---
## 📊 Параметры и их источники
| Параметр | Значение | Источник |
|----------|----------|----------|
| `hedge_cooldown_sec` | 5 сек | PositionSnapshot |
| `depth_threshold` | 1000.0 | Hardcoded |
| `hedge_trigger_pct` | -1.5% | Hardcoded (через проверку delta <= -1.5) |
| `emergency_hedge_pct` | -1.75% | Hardcoded (через проверка delta <= -1.75) |
| `last_entry_time` | timestamp | PositionSnapshot |
| `last_cooldown_log_time` | timestamp | PositionSnapshot |
| `entry_long` / `entry_short` | из PositionSnapshot | Redis / резки |
| `long_qty` / `short_qty` | из PositionSnapshot | Redis / биржа |
| `bid_qty_depth` | из TradingMeta | Gate.io API |
| `ask_qty_depth` | из TradingMeta | Gate.io API |
---
## 🔗 Интеграция с другими модулями
### 1. PositionSnapshot
**Используемые поля:**
```rust
pos.long_qty
pos.short_qty
pos.entry_long
pos.entry_short
pos.last_entry_time
pos.hedge_cooldown_sec
pos.last_cooldown_log_time
```
**Не изменяемые поля** (только чтение):
- `pos.last_cooldown_log_time` - обновляется при логировании
---
### 2. TradingMeta
**Используемые поля:**
```rust
meta.price
meta.bid_qty_depth
meta.ask_qty_depth
```
---
### 3. BothStrategy
**Связь:**
- HedgeGuard работает когда ТОЛЬКО одна сторона активна
- После хеджа → BOTH → BothStrategy берёт управление
---
## 🔄 Поток данных
```
live_step()
↓
HedgeGuard::check()
↓
├─→ Проверка цены
├─→ Проверка Cooldown
│ ├─→ elapsed < N сек → return None (логируем раз в сек)
│ └─→ elapsed >= N сек → продолжаем
│
├─→ Экстренная защита (пустой стакан)
│ ├─→ total_depth < 1000?
│ ├─→ delta <= -1.75%?
│ └─→ Some(HedgeSignal) ✅
│
├─→ Проверка дочедживания (BOTH)
│ └─→ long_qty <= short_qty → return None
│
├─→ Проверка LONG (одиночная)
│ ├─→ delta = (price - entry_long) / entry_long × 100
│ ├─→ delta <= -1.5%?
│ │ ├─→ Да → Some(HedgeSignal) ✅
│ │ └─→ Нет → продолжаем
│
└─→ Проверка SHORT (одиночная)
├─→ delta = (entry_short - price) / entry_short × 100
├─→ delta <= -1.5%?
│ ├─→ Да → Some(HedgeSignal) ✅
│ └─→ Нет → return None
If Some(HedgeSignal):
↓
HedgeGuard::execute()
↓
├─→ 🛡️ ХЕДЖ СИГНАЛ: reason
│
├─→ if long_qty > 0 && short_qty == 0:
│ └─→ OpenShort(add_short, price)
│
└─→ if short_qty > 0 && long_qty == 0:
└─→ OpenLong(add_long, price)
```
---
## 📝 Логирование
### Cooldown:
```
⏸️ ХЕДЖ НА ПАУЗЕ: прошло 1 сек из 5 сек cooldown
```
### LONG проверка:
```
📊 LONG хедж проверка: entry=0.002000, current=0.002010, delta_pct=+0.500%
```
### SHORT проверка:
```
📊 SHORT хедж проверка: entry=0.002000, current=0.001990, delta_pct=+0.500% (ПРИБЫЛЬ: цена вниз)
```
### Экстренный хедж:
```
🚨🚨 ЧРЕЗВЫЧАЙНЫЙ ХЕДЖ!
- Пустой стакан: depth=500.00 < 1000.00
- Резкое движение: -1.75% (экстренный порог ±1.75%)
```
### Хедж сигнал:
```
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge LONG: delta -1.5%, add SHORT 1000
```
### Actions:
```
📊 ХЕДЖ создал 1 actions
```
---
## 🚀 Использование в коде
### Пример вызова в live_step.rs:
```rust
// Проверяем хедж (если одиночная позиция)
if let Some(sig) = hedge_guard.check(&mut pos, meta, pos.entry_long) {
let actions = hedge_guard.execute(&pos, sig, meta.price);
if !actions.is_empty() {
return actions; // Исполняем действия
}
}
```
---
## 📊 Важные формулы
### 1. Delta LONG
```
delta_pct = (price - entry_long) / entry_long × 100
```
**Пример:**
```
entry_long = 0.002000
price = 0.001970
delta_pct = (0.001970 - 0.002000) / 0.002000 × 100 = -1.5%
```
### 2. Delta SHORT
```
delta_pct = (entry_short - price) / entry_short × 100
```
**Пример:**
```
entry_short = 0.002000
price = 0.002030
delta_pct = (0.002000 - 0.002030) / 0.002000 × 100 = -1.5%
```
### 3. Total Depth
```
total_depth = bid_qty_depth + ask_qty_depth
```
**Пример:**
```
bid_qty_depth = 500
ask_qty_depth = 300
total_depth = 800
```
---
## 🔍 Проверка работы
### Проверка 1: Правильная работа хеджа LONG
1. Открыть LONG позицию
2. Подождать 5 секунд (cooldown)
3. Дождаться падения цены на -1.5%
4. Проверить лог:
```
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5%
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge LONG: delta -1.5%, add SHORT 1000
📊 ХЕДЖ создал 1 actions
```
5. Проверить что открылся SHORT того же размера
### Проверка 2: Правильная работа хеджа SHORT
1. Открыть SHORT позицию
2. Подождать 5 секунд (cooldown)
3. Дождаться роста цены на +1.5%
4. Проверить лог:
```
🚨🚨 ЭКСТРЕННЫЙ ХЕЖ! delta_pct=-1.500% <= -1.5% (цена вверх против SHORT)
🛡️ ХЕДЖ СИГНАЛ: Auto-hedge SHORT: delta -1.5%, add LONG 1000
```
5. Проверить что открылся LONG того же размера
### Проверка 3: Правильная работа Cooldown
1. Открыть позицию
2. Сразу получить delta = -1.5% (в течение 1 секунды)
3. Проверить лог:
```
⏸️ ХЕДЖ НА ПАУЗЕ: прошло 1 сек из 5 сек cooldown
```
4. Проверить что хедж НЕ сработал
5. Подождать 5 секунд
6. Если delta всё ещё <= -1.5% → должен хеджироваться
### Проверка 4: Правильная работа экстренного хеджа
1. Открыть позицию
2. Имитировать пустой стакан (bid_qty_depth + ask_qty_depth < 1000)
3. Получить delta = -1.75%
4. Проверить лог:
```
🚨🚨 ЧРЕЗВЫЧАЙНЫЙ ХЕДЖ!
- Пустой стакан: depth=700.00 < 1000.00
- Резкое движение: -1.75% (экстренный порог ±1.75%)
```
5. Проверить что хедж сработал
---
## 📚 Связанные файлы
| Файл | Связь |
|------|-------|
| `src/live/state.rs` | PositionSnapshot структура |
| `src/live/meta.rs` | TradingMeta структура |
| `src/live/actions.rs` | LiveAction enum |
| `src/live/step.rs` | live_step orchestration |
| `src/live/strategy_both.rs` | BothStrategy (после хеджа) |
---
## 🎯 Резюме
**Что делает HedgeGuard:**
1. ✅ Проверяет условия хеджа при движении цены против позиции
2. ✅ Работает когда ТОЛЬКО одна сторона активна (LONG или SHORT)
3. ✅ Порог хеджа: `delta <= -1.5%`
4. ✅ Экстренный хедж при пустом стакане: `delta <= -1.75%`
5. ✅ Cooldown защита (5 секунд после входа)
6. ✅ Rate limiting логирования (1 раз в секунду при cooldown)
7. ✅ Защита от дочедживания если BOTH уже есть
8. ✅ Зеркальный хедж (открывает противоположную сторону того же размера)
9. ✅ Логирование каждые 5 секунд или при критических значениях
**Когда хеджируем:**
- ✅ `delta <= -1.5%` (обычный хедж)
- ✅ `total_depth < 1000` **и** `delta <= -1.75%` (экстренный хедж)
**Когда НЕ хеджируем:**
- ❌ Cooldown не прошёл (менее 5 секунд)
- ❌ BOTH уже есть и хедж достаточный
- ❌ Порог не достигнут (`delta > -1.5%`)
- ❌ BOTH режим (обе стороны)
**Особенности:**
- 🔥 Экстренная защита при пустом стакане
- 🔥 Rate limiting логирования
- 🔥 Защита от дочедживания
---
**Дата создания:** 2026-02-22
**Автор:** Claude Code Assistant
**Версия:** 1.0