← Назад к главному
# 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