🧪 Test Plan: Backtest Runner Skill (Mastra Agent)
Цель: Проверить стабильность, корректность загрузки данных и исполнения стратегий в изолированной среде Freqtrade (Docker).
Тестируемый инструмент: runBacktest
Зависимости: Docker, Santiment Data Service, Freqtrade Image.
🛠 Предварительные требования (Prerequisites)
- Environment: Локально запущенный Docker Desktop.
- Config: Заполненный
.env(доступ к SanR/Santiment API). - State: В рамках теста в "памяти" агента (или в файловой системе песочницы) должны существовать файлы
strategy.pyиconfig.json.
1. Функциональное тестирование: Базовая механика и Даты
Эти тесты проверяют, что инфраструктура работает, а данные корректно загружаются для разных эпох рынка.
✅ Тест-кейс 1.1: Исторический прогон (Deep History)
- Описание: Запуск простой стратегии на данных 2-3 летней давности.
- Цель: Убедиться, что API Santiment отдает архивные данные и Freqtrade корректно их обрабатывает.
- Входные данные:
- Стратегия:
SimpleStrategy(покупка RSI < 30, продажа RSI > 70). - Пара:
BTC/USDT:USDT(Фьючерсы). - Таймфрейм:
1d. - Timerange:
20210101-20210201(Январь 2021).
- Стратегия:
- Ожидаемый результат:
- Инструмент возвращает
success: true. - В логах нет ошибок
No data found. Total Trades> 0 (так как волатильность была высокой).- Графики и сделки соответствуют ценам 2021 года (30k-40k$).
- Инструмент возвращает
✅ Тест-кейс 1.2: Свежий прогон + Граничный случай (Single Day)
- Описание: Запуск теста за "вчера" или за один конкретный день.
- Цель: Проверить наличие свежих данных и работу механизма автоматического расширения дат (фикс проблемы "пустого бэктеста").
- Входные данные:
- Стратегия:
SimpleStrategy. - Timerange:
YYYYMMDD-YYYYMMDD(где дата начала равна дате конца, например20241201-20241201).
- Стратегия:
- Ожидаемый результат:
- Система автоматически расширяет диапазон до +1 дня (в логах агента видно предупреждение/фикс).
- Freqtrade успешно запускается и прогоняет 24 свечи (для 1h) или 288 (для 5m).
- Результат
success: true.
2. Логическое тестирование: Копитрейдинг (Copy Trading)
Самый важный блок. Проверяем, что сигналы превращаются в реальные сделки.
✅ Тест-кейс 2.1: Верификация входа в сделку (Signal Execution)
- Описание: Проверка стратегии, использующей
sdk.pyдля копирования сигналов конкретного трейдера. - Подготовка: Найти в SanR трейдера (например,
semacaилиbrian), у которого точно был сигнал в выбранный период. - Входные данные:
- Стратегия:
CopyTradeStrategy. Логика:# Pseudo-code if signal['direction'] == 'up': return enter_long if signal['direction'] == 'down': return enter_short - Конфиг: Включенная пара, по которой был сигнал (например,
ETH/USDT:USDT). - Timerange: Период, охватывающий этот сигнал.
- Стратегия:
- Ожидаемый результат:
prepareMarketDataзагружает данные для пары.- В логах стратегии (через
logger.info) видно: "Received signal UP for ETH". - Критично: В таблице результатов Freqtrade
Total Trades>= 1. - Время входа в сделку в отчете совпадает (с точностью до свечи) со временем сигнала в SanR.
3. Негативное тестирование и Обработка ошибок (Resilience)
Проверяем, как система ведет себя при сбоях.
✅ Тест-кейс 3.1: Runtime-ошибка в коде (Crash Test)
- Описание: Запуск стратегии с валидным синтаксисом, но ошибкой выполнения.
- Входные данные:
- Стратегия: В методе
populate_indicatorsдобавитьx = 1 / 0. - Timerange: Любой валидный.
- Стратегия: В методе
- Ожидаемый результат:
- Агент не падает.
- Инструмент возвращает
success: false(илиtrueс текстом ошибки, зависит от реализации парсера). - В поле
errorилиlogTailсодержится Python Traceback:ZeroDivisionError: division by zero. - Пользователю выводится понятное сообщение: "Произошла ошибка в коде стратегии...".
✅ Тест-кейс 3.2: Отсутствующие рыночные данные (Invalid Pair)
- Описание: Попытка запустить тест на несуществующей или делистинговой монете.
- Входные данные:
- Config:
pair_whitelist: ["SCAMTOKEN/USDT:USDT"]. - Timerange: Любой.
- Config:
- Ожидаемый результат:
- Бэктест не начинается (Docker не запускается).
- Ошибка отлавливается на этапе
prepareMarketData. - Сообщение об ошибке:
Missing slugs for pairs...илиData fetch failed.
4. Чек-лист для ручного тестирования (Manual QA)
Если автоматические тесты прошли, тестировщик должен проверить UX в диалоге с агентом:
- Попросить агента: "Протестируй стратегию за 2022 год". Агент должен сам сконвертировать это в формат
20220101-20221231. - Попросить: "Протестируй за последнюю неделю". Проверить, что даты корректны.
- После успешного теста спросить: "Какой был максимальный просад (drawdown)?". Агент должен прочитать это из логов (используя навык
backtest-reporter).
Пример кода для запуска Copy Trading теста (для разработчика)
Этот код можно использовать в scenarios.spec.ts для Тест-кейса 2.1:
it('Copy Trading: should open a trade when signal is present', async () => {
// 1. Setup Strategy that mimics Copy Trading logic
const copyStrategy = `
class Strategy(IStrategy):
def populate_indicators(self, dataframe, metadata):
# MOCK SIGNAL: Force a buy signal on specific date
dataframe['enter_long'] = 0
dataframe.loc[dataframe['date'] == '2024-01-15 12:00:00+00:00', 'enter_long'] = 1
return dataframe
# ... rest of required methods
`;
// 2. Run Test around that date
await setupArtifacts(copyStrategy, 'ETH/USDT:USDT');
const result = await runBacktest.execute({ timerange: '20240114-20240116' });
// 3. Assertions
expect(result.success).toBe(true);
// Проверяем, что сделка реально открылась
expect(result.logTail).toMatch(/Total Trades\s+\|\s+1/);
expect(result.logTail).toMatch(/Win Rate\s+\|\s+100%|0%/); // Сделка должна быть закрыта
});