← Назад к главному
# config.rs - Модуль конфигурации
## 📋 Назначение модуля
`Config` и `ApiKeys` - структуры для загрузки глобальной конфигурации и API ключей из переменных окружения.
**Основная логика:**
1. **Config** - загружает настройки из .env или использует значения по умолчанию
2. **ApiKeys** - загружает API ключи Gate.io из .env (обязательные поля)
**Используется в:**
- `main.rs` - загружает конфигурацию при старте
- `gate.rs` - загружает API ключи
---
## 🏗️ Структура модуля
### Структура `Config`
**Строки:** 17-53
```rust
#[derive(Clone, Debug, Deserialize)]
pub struct Config {
/// Redis URL
pub redis_url: String,
/// Идентификатор сессии
pub session_id: String,
/// Стартовый символ (не используется — LIVE берёт пару из SCAN)
pub symbol: String,
/// Резервный символ, если SCAN ничего не нашёл
pub fallback_symbol: String,
/// Пауза между LIVE-тиками (мс)
pub tick_delay_ms: u64,
/// Горизонт прогнозирования (для других модулей)
pub horizon_steps: usize,
pub horizon_step_pct: f64,
// ----------------------------------------------------
// Фильтрация волатильности для SCAN-движка
// ----------------------------------------------------
/// Минимальная волатильность (% за 24ч)
pub min_volatility_pct: f64,
/// Максимальная волатильность (% за 24ч)
pub max_volatility_pct: f64,
/// Сколько пар проверяет SCAN за тик
pub scan_pairs_count: usize,
/// Баланс USDT для расчёта размера позиции
pub balance_usdt: f64,
}
```
**Назначение:** Глобальная конфигурация запуска Trading AI
**Поля:**
| Поле | Тип | Переменная окружения | Значение по умолчанию | Описание |
|------|-----|---------------------|---------------------|----------|
| `redis_url` | String | `REDIS_URL` | `redis://127.0.0.1/` | URL подключения к Redis |
| `session_id` | String | `SESSION_ID` | `volatility-trader-1` | Идентификатор сессии |
| `symbol` | String | `START_SYMBOL` | `VOLATILE_PAIRS` | Стартовый символ (не используется) |
| `fallback_symbol` | String | `FALLBACK_SYMBOL` | `""` | Резервный символ (если SCAN ничего не нашёл) |
| `tick_delay_ms` | u64 | `TICK_DELAY_MS` | `100` | Пауза между LIVE-тиками (мс) |
| `horizon_steps` | usize | `HORIZON_STEPS` | `20` | Горизонт прогнозирования (шаги) |
| `horizon_step_pct` | f64 | `HORIZON_STEP_PCT` | `2.0` | Размер шага прогнозирования (%) |
| `min_volatility_pct` | f64 | `MIN_VOL_PCT` | `15.0` | Минимальная волатильность (% за 24ч) |
| `max_volatility_pct` | f64 | `MAX_VOL_PCT` | `1000.0` | Максимальная волатильность (% за 24ч) |
| `scan_pairs_count` | usize | `SCAN_PAIRS_COUNT` | `50` | Сколько пар проверяет SCAN |
| `balance_usdt` | f64 | `BALANCE_USDT` | `50.0` | Баланс USDT для расчёта позиции |
---
### Структура `ApiKeys`
**Строки:** 117-120
```rust
#[derive(Clone, Debug)]
pub struct ApiKeys {
pub gate_api_key: String,
pub gate_secret_key: String,
}
```
**Назначение:** API ключи для Gate.io
**Поля:**
| Поле | Тип | Переменная окружения | Обязательный? | Описание |
|------|-----|---------------------|---------------|----------|
| `gate_api_key` | String | `GATE_API_KEY` | ✅ Да | API ключ Gate.io |
| `gate_secret_key` | String | `GATE_SECRET_KEY` | ✅ Да | Секретный ключ Gate.io |
---
## 🔄 Основные функции
### Функция `Config::load()`
**Строки:** 56-111
**Сигнатура:**
```rust
pub fn load() -> Self
```
**Возвращает:**
- `Config` - загруженная конфигурация
**Алгоритм:**
---
#### Этап 1: Загрузка .env
**Строки:** 57-58
```rust
// Подтянем переменные окружения из .env, если он есть
let _ = dotenv();
```
**Что делает:**
- Пытается загрузить переменные окружения из файла `.env`
- Если файл отсутствует → продолжает работу (ошибка игнорируется)
---
#### Этап 2: Создание структуры Config
**Строки:** 60-109
```rust
Self {
redis_url: env::var("REDIS_URL")
.unwrap_or_else(|_| "redis://127.0.0.1/".to_string()),
session_id: env::var("SESSION_ID")
.unwrap_or_else(|_| "volatility-trader-1".to_string()),
// Стартовые значения — не используются напрямую, но нужны для init
symbol: env::var("START_SYMBOL")
.unwrap_or_else(|_| "VOLATILE_PAIRS".to_string()),
fallback_symbol: env::var("FALLBACK_SYMBOL")
.unwrap_or_else(|_| "".to_string()),
// LIVE режим: быстрые тики (ваш стандарт)
tick_delay_ms: env::var("TICK_DELAY_MS")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(100),
// Горизонт анализа (для внешних модулей)
horizon_steps: env::var("HORIZON_STEPS")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(20),
horizon_step_pct: env::var("HORIZON_STEP_PCT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(2.0),
// SCAN фильтрует сверх-волатильные пары (минимум 15% за 24ч)
min_volatility_pct: env::var("MIN_VOL_PCT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(15.0),
max_volatility_pct: env::var("MAX_VOL_PCT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(1000.0),
// Проверяем N пар из списка лидеров
scan_pairs_count: env::var("SCAN_PAIRS_COUNT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(50),
// Баланс USDT для расчёта размера позиции (3% от депо)
balance_usdt: env::var("BALANCE_USDT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(50.0),
}
```
**Логика загрузки:**
Для каждого поля:
1. `env::var("VAR_NAME")` - пытается получить переменную окружения
2. `.unwrap_or_else(|_| default)` - использует значение по умолчанию если не найдено
3. Для числовых значений: `.ok().and_then(|v| v.parse::().ok()).unwrap_or(default)` - парсит в нужный тип
**Пример загрузки строки:**
```rust
redis_url: env::var("REDIS_URL")
.unwrap_or_else(|_| "redis://127.0.0.1/".to_string())
```
**Пример загрузки числа:**
```rust
tick_delay_ms: env::var("TICK_DELAY_MS")
.ok() // Option
.and_then(|v| v.parse::().ok()) // Option
.unwrap_or(100) // u64 или 100
```
---
### Функция `ApiKeys::load()`
**Строки:** 122-137
**Сигнатура:**
```rust
pub fn load() -> Self
```
**Возвращает:**
- `ApiKeys` - загруженные API ключи
**Алгоритм:**
---
#### Этап 1: Загрузка .env
**Строки:** 124-125
```rust
// .env уже мог быть прочитан выше, но если нет — ничего страшного.
let _ = dotenv();
```
**Что делает:**
- Пытается загрузить .env (безопасно, если уже загружен)
---
#### Этап 2: Загрузка API ключей
**Строки:** 127-130
```rust
let gate_api_key = env::var("GATE_API_KEY")
.expect("GATE_API_KEY не найден в окружении (.env)");
let gate_secret_key = env::var("GATE_SECRET_KEY")
.expect("GATE_SECRET_KEY не найден в окружении (.env)");
```
**Что делает:**
- Загружает `GATE_API_KEY` из переменных окружения
- Загружает `GATE_SECRET_KEY` из переменных окружения
- Если ключ не найден → `expect` паникует с сообщением об ошибке
**Пример ошибки:**
```
thread 'main' panicked at 'GATE_API_KEY не найден в окружении (.env)', src/config.rs:128:20
```
---
#### Этап 3: Создание структуры ApiKeys
**Строки:** 132-135
```rust
Self {
gate_api_key,
gate_secret_key,
}
```
---
## 📊 Переменные окружения
### Переменные для `Config`
| Переменная | Тип | Обязательный? | Значение по умолчанию |
|-----------|-----|---------------|---------------------|
| `REDIS_URL` | String | ❌ Нет | `redis://127.0.0.1/` |
| `SESSION_ID` | String | ❌ Нет | `volatility-trader-1` |
| `START_SYMBOL` | String | ❌ Нет | `VOLATILE_PAIRS` |
| `FALLBACK_SYMBOL` | String | ❌ Нет | `""` |
| `TICK_DELAY_MS` | u64 | ❌ Нет | `100` |
| `HORIZON_STEPS` | usize | ❌ Нет | `20` |
| `HORIZON_STEP_PCT` | f64 | ❌ Нет | `2.0` |
| `MIN_VOL_PCT` | f64 | ❌ Нет | `15.0` |
| `MAX_VOL_PCT` | f64 | ❌ Нет | `1000.0` |
| `SCAN_PAIRS_COUNT` | usize | ❌ Нет | `50` |
| `BALANCE_USDT` | f64 | ❌ Нет | `50.0` |
### Переменные для `ApiKeys`
| Переменная | Тип | Обязательный? | Значение по умолчанию |
|-----------|-----|---------------|---------------------|
| `GATE_API_KEY` | String | ✅ Да | Нет |
| `GATE_SECRET_KEY` | String | ✅ Да | Нет |
---
## 📄 Пример файла .env
```
# Redis
REDIS_URL=redis://127.0.0.1:6379/
# Сессия
SESSION_ID=volatility-trader-1
# Стартовый символ (не используется)
START_SYMBOL=VOLATILE_PAIRS
FALLBACK_SYMBOL=
# LIVE режим
TICK_DELAY_MS=200
# Горизонт прогнозирования
HORIZON_STEPS=20
HORIZON_STEP_PCT=2.0
# SCAN фильтры
MIN_VOL_PCT=10.0
MAX_VOL_PCT=100.0
SCAN_PAIRS_COUNT=20
# Баланс для расчёта позиции
BALANCE_USDT=100.0
# Gate.io API ключи (ОБЯЗАТЕЛЬНО)
GATE_API_KEY=your_api_key_here
GATE_SECRET_KEY=your_secret_key_here
```
---
## ⚠️ Критические моменты
### 1. API ключи обязательны
**Строки:** 127-130
```rust
let gate_api_key = env::var("GATE_API_KEY")
.expect("GATE_API_KEY не найден в окружении (.env)");
```
**Что это значит:**
- Если `GATE_API_KEY` не найден → программа паникует
- Если `GATE_SECRET_KEY` не найден → программа паникует
**Решение:** Добавьте ключи в `.env` файл
---
### 2. tick_delay_ms влияет на скорость LIVE
**Строка:** 73-76
```rust
tick_delay_ms: env::var("TICK_DELAY_MS")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(100),
```
**Что это значит:**
- LIVE loop ждёт `tick_delay_ms` между итерациями
- Меньшее значение = более быстрая реакция
- Большое значение = меньшая нагрузка на API
**Рекомендации:**
- `100` мс - для быстрых пампов
- `200` мс - стандартное значение
- `500` мс - для медленных рынков
---
### 3. MIN_VOL_PCT и MAX_VOL_PCT влияют на SCAN
**Строки:** 89-96
```rust
min_volatility_pct: env::var("MIN_VOL_PCT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(15.0),
max_volatility_pct: env::var("MAX_VOL_PCT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(1000.0),
```
**Что это значит:**
- SCAN фильтрует пары с волатильностью `MIN_VOL_PCT` - `MAX_VOL_PCT`
- Параметр измеряется в процентах за 24 часа
- Если нет пар в диапазоне → используется fallback (7-2000%)
**Примеры:**
```
MIN_VOL_PCT=10.0, MAX_VOL_PCT=100.0
→ Ищем пампы 10-100%
MIN_VOL_PCT=15.0, MAX_VOL_PCT=1000.0 (по умолчанию)
→ Ищем пампы 15-1000%
```
---
### 4. BALANCE_USDT используется для расчёта размера позиции
**Строки:** 105-108
```rust
balance_usdt: env::var("BALANCE_USDT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(50.0),
```
**Что это значит:**
- `BALANCE_USDT` используется в `entry_calculator.rs` для расчёта размера позиции
- Это не реальный баланс, а параметр для расчётов
- Реальный баланс получается через `gate.get_real_balance_usdt()`
**Рекомендация:** Установите `BALANCE_USDT` равным 3-5% от реального депо
**Пример:**
```
Реальный депозит = 1000 USDT
BALANCE_USDT = 50.0 (5% от депо)
```
---
### 5. SCAN_PAIRS_COUNT влияет на производительность
**Строки:** 99-102
```rust
scan_pairs_count: env::var("SCAN_PAIRS_COUNT")
.ok()
.and_then(|v| v.parse::().ok())
.unwrap_or(50),
```
**Что это значит:**
- SCAN проверяет первые `SCAN_PAIRS_COUNT` пар из отфильтрованного списка
- Большее значение = больше кандидатов, но медленнее
- Меньшее значение = быстрее, но можно пропустить хорошую пару
**Рекомендации:**
- `20` - для быстрого поиска
- `50` - стандартное значение
- `100` - для более точного выбора
---
## 📚 Связанные файлы
| Файл | Связь |
|------|-------|
| `src/main.rs` | Использует Config::load() |
| `src/gate.rs` | Использует ApiKeys::load() |
| `src/live/entry_calculator.rs` | Использует balance_usdt |
| `src/monitor.rs` | Использует min_volatility_pct, max_volatility_pct, scan_pairs_count, tick_delay_ms |
---
## 🎯 Резюме
**Что делает config.rs:**
1. ✅ Загружает конфигурацию из переменных окружения
2. ✅ Использует значения по умолчанию если переменные не найдены
3. ✅ Загружает API ключи Gate.io (обязательные поля)
**Config поля:**
- `redis_url` - URL Redis (по умолчанию: `redis://127.0.0.1/`)
- `tick_delay_ms` - задержка между тиками (по умолчанию: 100 мс)
- `min_volatility_pct` - мин. волатильность (по умолчанию: 15.0%)
- `max_volatility_pct` - макс. волатильность (по умолчанию: 1000.0%)
- `scan_pairs_count` - количество пар для SCAN (по умолчанию: 50)
- `balance_usdt` - баланс для расчёта позиции (по умолчанию: 50.0 USDT)
**ApiKeys поля:**
- `gate_api_key` - API ключ Gate.io (обязательный)
- `gate_secret_key` - секретный ключ Gate.io (обязательный)
**Файл .env:**
- Не обязательный (есть значения по умолчанию)
- Обязательны только `GATE_API_KEY` и `GATE_SECRET_KEY`
---
**Дата создания:** 2026-02-22
**Автор:** Claude Code Assistant
**Версия:** 1.0